reactjs this.refs vs document.getElementById

51

如果我只有基本表单,是应该使用 this.refs 还是直接使用 document.getElementById

所谓的基本表单指的是:

export default class ForgetPasswordComponent extends React.Component {
  constructor(props) {
    super(props);

    this.handleSendEmail = this.handleSendEmail.bind(this);
  }

  handleSendEmail(e) {
    e.preventDefault();

    // this.refs.email.value
    // document.getElementById('email').value
  }

  render() {
    <form onSubmit={this.handleSendEmail}>
      <input id="email" ref="email" type="text" />
      <input type="submit" />
    </form>
  }
}

使用其中之一是否有不利影响?


3
如果单个页面中有多个“ForgetPasswordComponent”实例,或者有任何其他ID为“email”的元素,则可能会选择错误的元素。 - Isuru
如果我尽可能使id唯一(因为在html中id应该是唯一的),我是否仍然应该使用refs或ids?使用refs是否有缺点? - index
在React.js中,是否有类似于JavaScript中的document.getElementById()函数的功能? - James Gentes
1个回答

71
一般而言,refsdocument.getElementById更好,因为它更符合你的React代码的其他部分。在React中,每个组件类可以有多个组件实例。
正如@Isuru在评论中指出的那样:使用id是危险的,因为React不会阻止您在1个页面上拥有多个表单,然后您的DOM包含具有相同ID的多个输入。这是不允许的。
使用refs的另一个优点是,根据设计,您只能在定义它的上下文中访问refs。这迫使您使用props和state(可能还有存储),如果您需要在此上下文之外访问信息,则可以使用它们。
这是一个优点,因为您很少/没有机会破坏单向数据流,这将使您的代码更易于管理。

注意:在几乎所有情况下,可以完全避免使用 refs。这是 Netflix 的设计原则,从未使用过任何 refs,如 Steve McGuire(Netflix 的高级用户界面工程师)在 this video from reactjs conf 2016 (视频中的第9:58分钟)中所解释的。
在您的情况下,这意味着将电子邮件输入值放入表单状态中,添加 onChange 处理程序,并在提交事件中使用状态值。


3
在大多数情况下,您不需要使用它们中的任何一个,而应该使用value + onChange(或LinkedStateMixin)。 - Björn Boxstart
1
我已经了解了状态的使用,但由于实现中需要添加“value”、“onchangevalue”和“state”,而且当表单中有很多字段时,你会开始拥有很多这些东西,所以我有点犹豫使用它。那么,是真的建议使用value + state + onchange吗? - index
是的,与引用相比,它是更受欢迎的。引用是一种捷径,随着应用程序的增长,很可能会让您陷入调试噩梦中。 - wintvelt
4
如果通过props向子组件传递Refs,可能会增加你想要完成的操作的复杂性。如果你正在开发类似于嵌套滚动到顶部按钮之类的功能,我建议使用document.getElement..这样做会更简洁明了,并且不涉及状态相关的操作。在调用scrollTo之前,您可能需要添加检查以确认目标元素是否存在。然而,对于表单等事项,我强烈建议避免使用Refs或document.getElement,并找到一种使用状态来构建结构的方法。 - Jax Cavalera
2
具有讽刺意味的是,Netflix数据可视化主管Elijah Meeks在他2017年关于React + D3的讨论中推荐使用refs。链接:https://medium.com/@Elijah_Meeks/interactive-applications-with-react-d3-f76f7b3ebc71 - duhaime
1
哈哈,是的,自从这个问题和答案以来,有很多发展。现在使用material-ui,forward refs和useRef hook已经是司空见惯了。在这个问题的背景下,我仍然认为最好不要使用refs。但我猜“永远不要使用refs”的规则不再是一个硬性规则了。;) - wintvelt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接