我有两个使用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>
加入Fabian Schultz
发生这种情况是因为在第一种情况下,您将函数的引用传递给ref
。在初始呈现期间,引用的函数将是instantiate
(创建了一个实例),element
将传递给该函数。对于下面的渲染(重新渲染),这个实例保持不变。所以,React 不会调用这个函数,因为它已经被调用了。
但是,在第二种情况下,箭头函数作为值传入。因此,对于每次重新渲染,函数将再次作为值传递。这就产生了两个箭头函数实例。一个来自之前的渲染,第二个来自最近的渲染。由于这个原因,React nullifies
之前的函数实例。因此,它返回该函数前一个实例的null
,并返回该函数最近的实例的element
。
取点:对于ref
希望这对你有帮助!
这已经在React的Github问题上进行了简要讨论。我会试着解释这个,但是很难用语言来表达。
由于您在第二个示例中没有调用"智能"组件方法,因此每次重新呈现组件时,console.log(el)
都会发生,这意味着当特定节点(在本例中为您的输入)被删除并再次呈现时,无论el
是否实际更改,它也会调用。当它被React删除时,它返回null
,因为元素不再存在,即使它只是一小部分秒。似乎这样做是为了完成。
Dan Abramov在推特上对此做了一些解释。