引用回调属性未按预期工作

时间:2016-10-30 14:04:06

标签: javascript reactjs

我使用ref callback attribute的两个例子。第一个on有一个对回调函数的引用。第二个箭头函数声明为值。

第一个按预期工作。但是,第二个在连续渲染时记录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>

2 个答案:

答案 0 :(得分:3)

添加到 Fabian Schultz

这是因为在第一种情况下,您将函数的引用传递给ref。在初始渲染期间,引用的函数将为instantiate(创建实例),element将传递给该函数。对于以下渲染(重新渲染),此实例保持不变。因此,React 将不会调用此函数,因为它已被调用。

但是,在第二种情况下,箭头函数作为值传入。因此,对于每次重新渲染,函数将再次作为值传递。这导致箭头函数的两个实例。一个,来自前一个渲染,另一个来自最近的渲染。因此,React nullifies是函数的前一个实例。因此,它返回前一个函数实例的null,并将element返回给函数的最近实例。

要点:始终使用ref

的功能参考

希望这有帮助!

答案 1 :(得分:2)

这是discussed briefly on React's Github issues。我会试着解释一下这个问题,但是很难说出来。

因为你没有打电话给&#34; smart&#34;在第二个示例中的组件方法,每次重新呈现组件时都会发生console.log(el),这意味着当特定节点(在本例中为您的输入)被删除并再次呈现时,它也会调用,无论{{{} 1}}实际上已经改变了。当它被React删除时,它会返回el,因为该元素不再存在,即使它仅仅只有几分之一秒。似乎这样做是为了完成。

这里是丹·阿布拉莫夫(Dan Abramov)的tweet解释了这一点。