小编典典

为什么ref ='string'是“旧版”?

reactjs

他们在React文档中说:

React还支持在任何组件上使用字符串(而不是回调)作为ref prop,尽管 这种方法目前在大多数情况下都是传统的

https://facebook.github.io/react/docs/more-about-
refs.html

请看以下示例:

class Foo extends Component {
  render() {
    return <input onClick={() => this.action()} ref={input => (this._input = input)} />;
  }
  action() {
    console.log(this._input.value);
  }
}

为什么我更喜欢这个,而不是:

class Foo extends Component {
  render() {
    return <input onClick={() => this.action()} ref='input' />;
  }
  action() {
    console.log(this.refs.input.value);
  }
}

第二个例子看起来更加干净和容易。
是否存在不建议使用string方法的风险?

注意 :我正在寻找文档中声明的“官方”答案,我不是在询问个人喜好等等。


阅读 237

收藏
2020-07-22

共1个答案

小编典典

旧的refs
API可能更简单,但在某些极端情况下(例如在回调中使用时)可能会变得困难。各种静态分析对字符串也很麻烦。基于回调的API可以完成字符串API可以完成的所有工作
并且只需增加一点冗长即可完成 更多工作

class Repeat extends React.Component {
  render() {
    return <ul> {
      [...Array(+this.props.times)].map((_, i) => {
        return <li key={i}> { this.props.template(i)    } </li>
      })
    } </ul>
  }
}

class Hello extends React.Component {
  constructor() {
    super();
    this.refDict = {};
  }

  render() {
    return <Repeat times="3" template={i => <span ref= {el => this.refDict[i] = el}> Hello {i} </span>} />
           {/*                                    ^^^ Try doing this with the string API          */}
  }
}

可以从问题#1373中找到进一步的讨论,以及有关基于字符串的api可能出现的问题的更全面列表,其中引入了基于回调的api。我将在此处提供问题说明的列表:

ref API损坏有几个方面。

  • 您必须将this.refs [‘myname’]称为字符串,以兼容Closure Compiler Advanced Mode。

  • 它不允许单个实例具有多个所有者的概念。

  • 神奇的动态字符串可能会破坏VM中的优化。

  • 它必须始终保持一致,因为它是同步解决的。这意味着渲染的异步批处理会引入潜在的错误。

  • 当前,我们有一个获取同级引用的钩子,以便您可以将一个引用该同级的组件作为上下文引用。这仅适用于一个级别。这破坏了将其中一个封装在封装中的能力。

  • 不能静态输入。您必须在任何类型的语言(如TypeScript)上使用它。

  • 在子级调用的回调中,无法将引用附加到正确的“所有者”。<Child renderer={index => <div ref="test">{index}</div>} />-此引用将附加在发出回调的位置,而不是当前所有者。


文档将旧的字符串API称为 “旧版”
,以更清楚地表明基于回调的API是首选方法,如本提交本PR中所讨论的,这实际上是将这些语句首先放在文档中的方法。地点。还要注意,一些注释暗示基于字符串的refs
api可能会在某个时候被 弃用

2020-07-22