Ref回调属性没有按预期工作

Ref callback attribute is not working as expected

本文关键字:工作 回调 属性 Ref      更新时间:2023-09-26

我有两个使用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在推特上对此做了一些解释。