Реагировать: Потеря значений ref
Я использую два компонента и использую этот шаблон: дочерний компонент должен оставаться изолированным настолько, насколько это возможно - он обрабатывает свою собственную ошибку проверки. Родительский компонент должен проверять наличие ошибок, которые имеют зависимости между дочерними элементами. Итак, в моем случае: password
поле и password confirmation
поле.
Вот мой код:
а) Регистрация (родитель)
Установка начального состояния.
constructor() {
super();
this.state = {
isPasswordMatching: false
};
}
В render()
Метод Я выводить свой дочерний компонент. Через реквизит callback
Я пропагандирую метод isPasswordMatching()
связывая родителей this
, Цель состоит в том, чтобы метод вызывался в дочернем компоненте.
<TextInput
id={'password'}
ref={(ref) => this.password = ref}
callback={this.isPasswordMatching.bind(this)}
// some other unimportant props
/>
<TextInput
id={'passwordConfirm'}
ref={(ref) => this.passwordConfirm = ref}
...
isPasswordMatching()
метод проверяет, совпадают ли пароли (через ссылки this.password
а также this.passwordConfirm
), а затем обновляет состояние. Обратите внимание, что этот метод вызывается внутри дочернего элемента (password или passwordConfirm).
isPasswordMatching() {
this.setState({
isPasswordMatching: this.password.state.value === this.passwordConfirm.state.value
});
}
б) TextInput (дочерний)
Установка начального состояния.
constructor() {
super();
this.state = {
value: '',
isValid: false
};
}
При размытии проверка выполняется и состояние обновляется.
onBlur(event) {
// doing validation and preparing error messages
this.setState({
value: value,
isValid: this.error === null
});
}
Самый последний. Callback реквизит называется.
componentDidUpdate(prevProps) {
if (prevProps.id === 'password' || prevProps.id === 'passwordConfirm') {
prevProps.callback();
}
}
вопрос
Каким-то образом мои реферы потеряны. Сценарий:
- Родительский компонент - это рендер
- Дочерние компоненты отображаются
- Я вхожу в одно из полей ввода и выхожу (это вызывает
onBlur()
метод) - состояние обновляется, дочерний компонент отображается componentDidUpdate()
вызывается иprevProp.callback()
также- Когда собираешься
isPasswordMatching()
метод, который я вывожуthis.password
а такжеthis.passwordConfirm
- это объекты с ожидаемыми значениями привязки. Обновление состояния родительского компонента отображается. - Затем снова отображаются все дочерние элементы, обновляются компоненты, вызывается обратный вызов, но на этот раз
this.password
а такжеthis.passwordConfirm
являютсяnull
,
Я понятия не имею, почему ссылки вроде бы потеряны. Должен ли я делать что-то по-другому? Заранее спасибо.
2 ответа
Смотрите документацию по реагированию здесь с важными предупреждениями и советами о том, когда использовать или не использовать ссылки.
Обратите внимание, что, когда указанный компонент отключен и всякий раз, когда ссылка изменяется, старая ссылка будет вызываться с нулем в качестве аргумента. Это предотвращает утечки памяти в случае сохранения экземпляра, как во втором примере. Также обратите внимание, что при написании ссылок с выражениями встроенных функций, как в примерах здесь, React каждый раз видит разные объекты функций, поэтому при каждом обновлении ref будет вызываться с нулем непосредственно перед вызовом с экземпляром компонента.
Я не уверен, отвечает ли это на вопрос @be-codified, но я обнаружил, что это сталкивается с похожей проблемой. В моем случае оказалось, что это связано с использованием функционального компонента.
https://reactjs.org/docs/refs-and-the-dom.html
Ссылки и функциональные компоненты. Вы не можете использовать атрибут ref на функциональных компонентах, потому что они этого не делают. Вам следует преобразовать компонент в класс, если вам требуется ссылка на него, так же, как вы это делаете, когда вам нужны методы или состояние жизненного цикла.
Однако вы можете использовать атрибут ref внутри функционального компонента, если вы ссылаетесь на элемент DOM или компонент класса.
Документация объясняет, что вы должны сделать, чтобы решить проблему, если у вас есть контроль над компонентом, который вы пытаетесь визуализировать.
Однако в моем случае компонент был из сторонней библиотеки. Таким образом, простая упаковка компонента работала нормально.
За работой
<div ref={element => this.elementName = element}>
<FunctionalComponent />
</div>
Не работает
устанавливает this.elementName вnull
<FunctionalComponent ref={element => this.elementName = element} />
Надеюсь, это поможет любому найти этот вопрос, как я.