小猿大圣

Refs 和 DOM - React官方文档

小猿大圣 · 2016-12-07翻译 · 1285阅读 原文链接

在典型的 React 数据流中, props 是父组件与子组件互动的唯一方法。 想要修改子组件,你要用新的props重新渲染它。 然而, 有些情况你必须在典型的React数据流之外强制修改子组件。被修改的子组件可以是一个React组件实例,也可以是一个DOM 元素。 对于这两种情况, React 提供了一种应急方案。

ref 回调属性

React 支持一个特殊的属性ref,您可以通过它连接到任何组件。ref 带有一个回调函数,并且回调函数在组件挂载或者卸载时将立即执行。

ref 属性用在HTML元素上时, ref 回调函数接收一个潜在的DOM元素作为它的参数。 例如, 这段代码用 ref 回调函数存储一个DOM节点的引用:

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.focus = this.focus.bind(this);
  }

  focus() {
    // 用原生的DOM API明确文本输入框的焦点
    this.textInput.focus();
  }

  render() {
    // 用ref回调函数存储一个文本输入DOM节点的引用
    // element in this.textInput.
    return (
      <div>
        &lt;input
          type="text"
          ref={(input) =&gt; { this.textInput = input; }} /&gt;
        &lt;input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        /&gt;
      </div>
    );
  }
}

当组件挂载时,React将触发在 DOM 元素上的ref 回调函数, 当它卸载时,以 null触发回调函数。

在类里用ref 回调函数设置属性是访问 DOM 元素的常用模式。 如果你当前用 this.refs.myRefName 访问 refs, 我们建议用以上这种模式代替。

ref属性被用在自定义的组件上,ref 回调函数接收挂载的组件实例作为它的参数。例如,如果我们想封装CustomTextInput ,在其上模拟被点击后立即挂载:

class AutoFocusTextInput extends React.Component {
  componentDidMount() {
    this.textInput.focus();
  }

  render() {
    return (
      &lt;CustomTextInput
        ref={(input) =&gt; { this.textInput = input; }} /&gt;
    );
  }
}

你可能在功能性组件上使用ref 属性,因为它们没有实例。 然而,你可以这样做, 在功能性组件的render 功能里面使用ref属性:

function CustomTextInput(props) {
  // textInput 必须在这声明以便ref回调函数能找到它
  let textInput = null;

  function handleClick() {
    textInput.focus();
  }

  return (
    <div>
      &lt;input
        type="text"
        ref={(input) =&gt; { textInput = input; }} /&gt;
      &lt;input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      /&gt;
    </div>
  );  
}

不要过度使用 Refs

你的第一意愿可能是用refs在你的应用里实现 "让事情发生" 。 如果是这样的话, 花一点时间更仔细的考虑state应该属于组件的那个层级。常常, 很显然,放在合适地方的state 在层次结构中处于一个更高的层次。 看这个 Lifting State Up 译文地址例子指南

相关文章