2016-10-30 3 views
1

У меня есть два примера, используя ref callback attribute. Первая функция имеет ссылку на функцию обратного вызова. Вторая имеет анонимную функцию, объявленную как значение.Атрибут обратного вызова ref работает не так, как ожидалось

Первые работы, как и ожидалось. Но, во-вторых, запишите null на последовательных рендерах.

Что является причиной этого?

Пример 1 (это работает отлично)

class App extends React.Component{ 
 
    constructor(props){ 
 
    super(props) 
 
    this.refCallback = this.refCallback.bind(this) 
 
    this.state = {} 
 
    } 
 
    
 
    refCallback(el){ 
 
    console.log(el) 
 
    } 
 
    
 
    render(){ 
 
    return <input type="text" 
 
     value={this.state.value} 
 
     ref={this.refCallback} 
 
     onChange={(e) => this.setState({value: e.target.value})} 
 
     /> 
 
    } 
 
} 
 

 
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>

Пример 2 (это не работает)

class App extends React.Component{ 
 
    constructor(props){ 
 
    super(props) 
 
    this.state = {} 
 
    } 
 

 
    render(){ 
 
    return <input type="text" 
 
     value={this.state.value} 
 
     ref={(el) => console.log(el)} 
 
     onChange={(e) => this.setState({value: e.target.value})} 
 
     /> 
 
    } 
 
} 
 

 
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>

+0

'<входной тип = "текст" значение = {this.state.value} исх = "все" OnChange = {() => this.setState ({значение: this.refs.whatever.value})} /> ' –

+0

Я знаю, что' ref string' будет работать.Мне нужно знать об атрибуте ref refback. React будет обесценивать 'string ref' в будущих выпусках. –

+0

' this.whatever = ref} onChange = {() => this.setState ({значение: this.whatever .input.value})} /> ' –

ответ

1

Это было discussed briefly on React's Github issues. Я постараюсь это объяснить, но трудно сказать.

Поскольку во втором примере вы не вызываете «интеллектуальный» компонент, то console.log(el) происходит каждый раз, когда компонент перерисовывается, что означает, что он также вызывает, когда конкретный узел (в данном случае ваш вход) удаляется и отображается снова, независимо от того, действительно ли el изменился. Когда он удаляется React, он возвращает null, потому что элемент больше не существует, даже если он всего лишь на долю секунды. Похоже, это делается ради завершения.

Подробнее об этом объясните tweet от Dan Abramov.

+0

Выглядит интересно. Спасибо за ссылки. После этого это одобрит! –

+0

Я добавил подробный ответ ниже. Проверьте, правильно ли это! Спасибо –

2

Добавление к Fabian Шульца

Это происходит потому, что в первом случае, вы передаете ссылку функции на ref. Во время первоначального рендеринга ссылочная функция будет равна instantiate (создается экземпляр), и element будет передан этой функции. Для следующих рендерингов (переопределений) этот экземпляр остается неизменным. Итак, React не будет вызовет эту функцию, поскольку она уже вызывается.

Но во втором случае функция стрелки передается как значение. Таким образом, для каждого повторного выполнения функция будет передаваться снова как значение. Это приводит к двум случаям функций стрелок. Один, от предыдущего рендера и второй от последнего рендера. В связи с этим, React nullifies предыдущий экземпляр функции. Таким образом, он возвращает null для предыдущего экземпляра функции и возвращает element последнему экземпляру функции.

точки взять: Всегда используйте ссылку на функцию для ref

Надеется, что это помогает!

+0

Я попробовал это с этим, и он, кажется, ничего не исправляет. – swyx