【问题标题】:Ref callback attribute is not working as expectedRef 回调属性未按预期工作
【发布时间】:2018-05-23 20:18:47
【问题描述】:

我有两个使用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>

【问题讨论】:

  • &lt;input type="text" value={this.state.value} ref="whatever" onChange={() =&gt; this.setState({value: this.refs.whatever.value})} /&gt;
  • 我知道ref string 会起作用。我需要了解ref callback attribute。 React 将在未来的版本中弃用 string ref
  • &lt;input type="text" value={this.state.value} ref={ref =&gt; this.whatever = ref} onChange={() =&gt; this.setState({value: this.whatever.input.value})} /&gt;

标签: javascript reactjs


【解决方案1】:

添加到 Fabian Schultz

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

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

要点:始终使用ref的函数引用

希望这会有所帮助!

【讨论】:

  • 我用这个试过了,它似乎没有解决任何问题。
【解决方案2】:

这是discussed briefly on React's Github issues。我会尝试解释这一点,但很难用语言表达。

由于您在第二个示例中没有调用“智能”组件方法,因此每次重新渲染组件时都会发生console.log(el),这意味着它也会在特定节点(在本例中为您的输入)时调用无论el 是否实际更改,都将被删除并再次呈现。当它被 React 删除时,它会返回 null,因为该元素不再存在,即使它只存在几分之一秒。看来这是为了完成。

这是 Dan Abramov 的 tweet 对此进行了一些解释。

【讨论】:

  • 看起来很有趣。感谢您的链接。过段时间会批准的!
  • 我在下面添加了详细的答案。检查是否正确!谢谢
猜你喜欢
  • 2020-12-17
  • 1970-01-01
  • 2020-04-26
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多