三. React的Refs 和 DOM

在少数情况下,需要在常规数据流外强制修改子元素。被修改的子元素可以是 React 组件实例,或者是一个 DOM 元素。在这种情况下,React 提供了解决办法。

一. 何时使用 Refs

  • 处理focus、文本选择或者媒体播放
  • 触发强制动画
  • 集成第三方DOM库

如果可以通过声明式实现,就尽量避免使用 refs 。

不要过度使用 Refs,尽量在组件层使用state,因为state更为清晰。

二. 在 DOM 元素上添加 Ref

React 支持给任何组件添加特殊属性。ref属性接受回调函数,并且当组件 装载(mounted) 或者 卸载(unmounted) 之后,回调函数会立即执行。

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

  focus() {
    // 通过使用原生API,显式地聚焦text输入框
    this.textInput.focus();
  }

  render() {
    // 在实例中通过使用`ref`回调函数来存储text输入框的DOM元素引用(例如:this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={input =>  this.textInput = input; } />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />

      </div>
    );

使用 ref 回调只是为了在类上设置一个属性,是访问 DOM 元素的常见模式。

三. 为 类(Class) 组件添加 Ref

ref属性用于类(class)声明的自定义组件时,ref回调函数收到的参数是装载(mounted)的组件实例。例如,如果我们想包装CustomTextInput组件,实现组件在 装载(mounted) 后立即点击的效果:

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

  render() {
    return (
      <CustomTextInput
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

注:这种方式仅对以类(class)声明的component有效:

class CustomTextInput extends React.Component {
  // ...
}

四. Refs 与 函数式组件

不能在函数式组件上使用 ref 属性,因为它们没有实例:

function MyFunctionalComponent() {
  return <input />;
}

class Parent extends React.Component {
  render() {
    // 这里 *不会* 执行!
    return (
      <MyFunctionalComponent
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

但是可以在函数式组件内部使用 ref来引用一个 DOM 元素或者 类(class)组件:

function CustomTextInput(props) {
  // textInput必须在这里声明,所以 ref 回调可以引用它
  let textInput = null;

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

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

推荐阅读更多精彩内容

  • refs提供了可以在render方法中访问dom节点和创建的react元素的方法。 为了良好的阅读体验,请查看gi...
    mytac阅读 438评论 0 1
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 6,894评论 7 41
  • 微博 作者是 SINA Corporation (Nasdaq: SINA) https://itunes.app...
    zolipi阅读 215评论 0 0
  • 自古就有成者王候败者寇这一说词,从古至今无不例外,人们赞颂的永远都是胜者的事迹,而那些被打败的人会被遗弃。 一个人...
    hwc阅读 183评论 0 2
  • 满眼茅竹翠欲滴,山高煦旭露初收。 蜩鸣树盖生凉意,路转崎危惹客愁。 故地微尘寻旧迹,枕水依山任去留。
    海1619阅读 193评论 0 7