React Ref

React Ref

何时使用Refs

  • 管理焦点,文本选择或者媒体播放

  • 触发强制动画

  • 继承第三放DOM库

避免使用refs来做任何可以通过声明式实现来完成的事件

创建Ref

Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

访问Refs

当ref被传递给render中的元素时,对该节点的引用可以在ref的current属性中被访问到

const node = this.myRef.current;

ref的值根据节点的类型而有所不同:

  • ref属性用于HTML元素时,构造函数中使用React.createRef()创建的ref接收底层DOM元素作为其current属性
  • ref属性用于自定义class组件,ref对象接收组件的挂载示例作为current属性
  • 不能在函数组件上使用ref属性,因为他们没有实例

为DOM元素添加ref

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:我们通过 "current" 来访问 DOM 节点
    this.textInput.current.focus();
  }

  render() {
    // 告诉 React 我们想把 <input> ref 关联到
    // 构造器里创建的 `textInput` 上
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

React 会在组件挂载时给 current 属性传入 DOM 元素,并在组件卸载时传入 null 值。ref 会在 componentDidMountcomponentDidUpdate 生命周期钩子触发前更新。

class组件添加Ref

如果我们想包装上面的 CustomTextInput,来模拟它挂载之后立即被点击的操作,我们可以使用 ref 来获取这个自定义的 input 组件并手动调用它的 focusTextInput 方法:

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

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

请注意,这仅在 CustomTextInput 声明为 class 时才有效:

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

回调Refs

React也支持另一种i设置refs的方法,称为回调refs。它能助你更精准地控制何时refs被设置和解除

不同于传递createRef()创建ref属性,你会传递一个函数。这个函数中接收React组件实例或HTML DOM元素作为参数,以使它们能在其他地方被存储和访问

 render() {
    return (
      <div>
        <input
          type="text"
          ref={(element) => {this.textInput = element}}
        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }

React将在组件挂载时,会调用ref回调函数传入DOM元素,当卸载时会调用它并传入null

回调refs的扩展

如果ref回调函数是以内联函数的方式定义的,即如以上代码所写,在更新过程(不包含初次渲染)中它会执行两次,第一次传入参数null,然后第二次传入参数DOM元素。

这是因为每次渲染会创建一个新的实例,所以React清空旧的ref并且设置新得。通过将ref的回调定义成class绑定方式可以避免以上问题

saveInput = (c) => {
    this.input1 = c
} 

render() {
    return (
      <div>
        <input
          type="text"
          ref={this.saveInput}
        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值