13-Refs and the DOM

Refs and the DOM

在典型的React数据流中,props是父级组件与子组件交互的唯一方式。为了修改一个子组件需要用新的props来渲染。然而,存在一些情况需要--脱离典型数据流的方式去修改子组件。子组件可以作为一个React组件或DOM元素来修改。

When to Use Refs

这里有几种使用refs的情况

  • 管理焦点、文本选择、多媒体播放
  • 触发指令动画
  • 和第三方DOM库交互

给DOM元素增加一个ref属性

React支持一个特殊的属性,这个属性可以添加在任何组件中。ref属性指向了一个callback function(回调函数),这个回调函数会在组件加载或卸载后立即执行

当ref属性被用于HTML元素时,ref指向的回调函数接收当前DOM元素作为参数。例如,下面的代码使用ref回调函数去存储一个DOM节点的引用

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

  focus() {
    // Explicitly focus the text input using the raw DOM API
    this.textInput.focus();
  }

  render() {
    // Use the `ref` callback to store a reference to the text input DOM
    // element in an instance field (for example, this.textInput).
    // 注意:ref中的参数input指的是<input type="text"...这个dom元素,参数input只是个参数名,可以换其他参数名
    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />
      </div>
    );
  }
}

React会在组件装载时调用回调函数以DOM元素作为参数,当被卸载时调用回调函数并将null作为参数

在Class组件中添加ref

当ref属性被用于自定义类组件时,这个ref回调函数 接受一个已经加载的组件实例作为参数

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

  focus() {
    // Explicitly focus the text input using the raw DOM API
    this.textInput.focus();
  }

  render() {
    // Use the `ref` callback to store a reference to the text input DOM
    // element in an instance field (for example, this.textInput).
    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
      </div>
    );
  }
}
class AutoFocusTextInput extends React.Component {
  componentDidMount() {
    // 这里的focus方法实际上是CustomTextInput组件实例的focus方法
    this.textInput.focus();
  }
  // 这里的ref中的参数input指的是已经加载完毕的CustomTextInput组件实例,然后将this.textInput指向该实例
  render() {
    return (
      <CustomTextInput
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

Refs和函数式组件

  • 不能在函数式组件中使用ref属性,因为函数式组件没有实例
function MyFunctionalComponent() {
  return <input />;
}

class Parent extends React.Component {
  render() {
    // This will *not* work!
    // 由于函数式组件没有实例,因此ref中的参数input其实不是一个组件实例,因此无法通过这种方式获得组件实例的引用
    return (
      <MyFunctionalComponent
        ref={(input) => { this.textInput = input; }} />
    );
  }
}
  • 如果引用了DOM元素或者类组件,也是可以在函数式组件中使用ref属性的
function CustomTextInput(props) {
  // textInput must be declared here so the ref callback can refer to it
  let textInput = null;

  function handleClick() {
    textInput.focus();
  }
  // 这里ref中的input参数指的就是该<input type="text".....元素
  return (
    <div>
      <input
        type="text"
        ref={(input) => { textInput = input; }} />
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );  
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容