2016-07-15 5 views
10

Я использую два компонента, и я использую этот шаблон: дочерний компонент должен оставаться изолированным как можно больше - он обрабатывает собственную ошибку проверки. Родительский компонент должен проверять наличие ошибок, которые имеют зависимости между дочерними элементами. Итак, в моем случае: password поле и password confirmation поле.React: Losing ref values ​​

Вот мой код:

а) SignUp (родитель)

Установка начального состояния.

constructor() { 
    super(); 

    this.state = { 
     isPasswordMatching: false 
    }; 
} 

Метод render() Я выводил свой дочерний компонент. Через prop под названием 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), а затем обновляет состояние. Обратите внимание, что этот метод вызывается внутри дочернего элемента (пароль или парольConfirm).

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 
    }); 
} 

Последние. Вызывается функция обратного вызова.

componentDidUpdate(prevProps) { 
    if (prevProps.id === 'password' || prevProps.id === 'passwordConfirm') { 
     prevProps.callback(); 
    } 
} 

Выпуск

Как-то мои рефов теряются. Сценарий:

  1. компонент Родитель renderder
  2. компоненты по уходу за детьми предоставляются
  3. Я вхожу один из полей ввода и выйти (это вызывает onBlur() метод) - состояние обновляется, ребенок компонент оказывается
  4. componentDidUpdate() и prevProp.callback()
  5. При переходе на isPasswordMatching() метод вывода this.password и this.passwordConfirm - это объекты с ожидаемыми значениями ссылки. Обновляется состояние родительского компонента.
  6. Затем все дети визуализируются, компоненты обновляются, вызывается обратный вызов, но на этот раз this.password и this.passwordConfirm - null.

Я понятия не имею, почему ссылки потеряны. Должен ли я делать что-то по-другому? Спасибо заранее.

ответ

6

См. react documentation here с важными предупреждениями и советом, когда использовать или не использовать ссылки.

Обратите внимание, что когда ссылочный компонент отключен и всякий раз, когда изменяется ссылка, старый ref будет вызываться с нулевым аргументом. Это предотвращает утечку памяти в том случае, если экземпляр хранится, как во втором примере. Также обратите внимание, что при написании ссылок с встроенными выражениями функций, как в приведенных здесь примерах, React видит каждый раз каждый объект-объект, поэтому при каждом обновлении ref будет вызываться с нулевым значением непосредственно перед его вызовом с экземпляром компонента.

+0

Благодарим вас за усилия. О, так это моя проблема. У вас есть какие-то указатели, как мне это решить? Должен ли я использовать контекст? –

+0

Спасибо. Это, похоже, было потеряно в обновлении документации. –

0

Я не уверен, что это отвечает на вопрос @ be-codified для нет, но я нашел, что это работает в аналогичной проблеме. В моем случае оказалось, что это связано с использованием функционального компонента.

https://reactjs.org/docs/refs-and-the-dom.html#refs-and-functional-components

Refs и функциональные компоненты Вы не можете использовать атрибут реф на функциональных компонентах, потому что они не Вы должны преобразовать компонент в классе, если вам нужно реф к нему, так же, как вы делаете, когда вам нужны методы жизненного цикла или состояние.
Вы можете, однако, использовать реф атрибут внутри функционального компонента, если вы обратитесь к DOM элемента или класс компоненту

документации объясняет, что вы должны сделать, чтобы решить эту проблему, если у вас есть контроль компонент, который вы пытаетесь выполнить.

Однако в моем случае компонент был из сторонней библиотеки. Таким образом, просто обертка компонента работала нормально.

Работа

<div ref={element => this.elementName = element}> 
    <FunctionalComponent /> 
</div> 

не работают
наборов this.elementName к null

<FunctionalComponent ref={element => this.elementName = element} /> 

Надеется, что это помогает кто-нибудь найти этот вопрос, как я сделал.

Смежные вопросы