我使用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>
答案 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解释了这一点。