reactjs - 为什么 ref ='string' 是 "legacy"?

标签 reactjs

在 React 文档中他们说:

React also supports using a string (instead of a callback) as a ref prop on any component, although this approach is mostly legacy at this point.

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);
  }
}

第二个示例似乎更干净、更简单。
字符串方法是否存在被弃用的风险?


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

最佳答案

虽然可能更简单,但旧的 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          */}
  }
}

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

The ref API is broken is several aspects.

  • You have to refer to this.refs['myname'] as strings to be Closure Compiler Advanced Mode compatible.

  • It doesn't allow the notion of multiple owners of a single instance.

  • Magical dynamic strings potentially break optimizations in VMs.

  • It needs to be always consistent, because it's synchronously resolved. This means that asynchronous batching of rendering introduces potential bugs.

  • We currently have a hook to get sibling refs so that you can have one component refer to it's sibling as a context reference. This only works one level. This breaks the ability to wrap one of those in an encapsulation.

  • It can't be statically typed. You have to cast it at any use in languages like TypeScript.

  • There's no way to attach the ref to the correct "owner" in a callback invoked by a child. <Child renderer={index => <div ref="test">{index}</div>} /> -- this ref will be attached where the callback is issued, not in the current owner.

<小时/>

文档将旧字符串 API 称为“旧版”,以明确基于回调的 API 是首选方法,如 this commit 中所述。并在 this PR那些实际上首先将这些陈述放入文档中的人。另请注意,一些评论暗示基于字符串的 refs api 可能会在某个时候被弃用。

关于reactjs - 为什么 ref ='string' 是 "legacy"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37468913/

相关文章:

javascript - 如何通过从父组件作为 Prop 传递的状态在子组件中切换 setInterval

reactjs - render() 中的 connect() ?

javascript - 未捕获的 TypeError : data. Push 不是一个函数。如何解决此推送错误?

javascript - Reactjs onClick : how to set state of clicked buttons in a list

javascript - React-testing-library:在组件的上下文中找不到 "store"

javascript - 超出最大调用堆栈大小 - Connected React Component

javascript - 如何在 PHP 和 Javascript 之间隐藏我的 API key ?

reactjs - 错误 og :image is appearing on page metadata

css - 使用 React 和 CSS Modules/PostCSS 制作可自定义的 css 属性

reactjs - react : Unexpected token return