为什么 ref='string' 是“遗留的"? [英] Why ref='string' is "legacy"?

查看:68
本文介绍了为什么 ref='string' 是“遗留的"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 React 文档中他们说:

In the React documentation they say:

React 还支持在任何组件上使用字符串(而不是回调)作为 ref 属性,尽管这种方法目前大多是遗留的.

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

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

Why should I prefer this, instead of:

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

?

第二个例子似乎更干净、更容易.
字符串方法是否有被弃用的风险?

It seems just much more clean and easier the second example.
Are there risks that the string method will be deprecated?


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


NB: I'm looking for the "official" answer to the statement in the documentation, I'm not asking about personal preferences and so on.

推荐答案

虽然可能更简单,但旧的 refs API 在某些边缘情况下可能会变得困难,例如在回调中使用时.所有类型的静态分析对于字符串也是一种痛苦.基于回调的 API 可以做字符串 API 可以做的所有事情甚至更多,只是稍微增加了一点冗长.

While perhaps more simple, the old refs API can get difficult in some edge cases, like when used in a callback. All kind of static analysis is a pain with strings, too. The callback based API can do everything the string API can do and more with just a little added verbosity.

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.我将在此处列出问题描述中的列表:

Further discussion and a bit more comprehensive list of the possible issues with the string based api can be found from issue #1373, where the callback based api was introduced. I'll include here a list from the issue description:

ref API 有几个方面的问题.

The ref API is broken is several aspects.

  • 您必须将 this.refs['myname'] 称为字符串才能与 Closure Compiler Advanced Mode 兼容.

  • 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.

它不能是静态类型的.在 TypeScript 之类的语言中,您必须在任何用途中使用它.

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

无法将引用附加到正确的所有者"在孩子调用的回调中.<子渲染器={index =><div ref="test">{index}</div>}/> -- 此 ref 将附加在发出回调的位置,而不是在当前所有者中.

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 legacy" 以更清楚地表明基于回调的 API 是首选方法,如 此提交这个 PR 是那些实际上首先将这些陈述放入文档的人.另请注意,一些注释暗示基于字符串的 refs api 可能会在某些时候弃用.


The docs call the old string API "legacy" to make it clearer that the callback-based API is the preferred approach, as is discussed in this commit and in this PR which are the ones that actually put those statements to the documentation in the first place. Also note that a few of the comments imply that the string based refs api might be deprecated at some point.

这篇关于为什么 ref='string' 是“遗留的"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆