了解一下refs

Posted let423

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解一下refs相关的知识,希望对你有一定的参考价值。

1. Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素

2. 在典型的React数据流中,`props`是父组件与子组件交互的唯一方式,要修改一个子组件,需要使用新的props来重新渲染它。但是在某些情况下需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个React组件的实例,也可能是一个DOM元素

3. 过时API:String 类型的 Refs

一、何时使用 Refs

  • 管理焦点,文本选择或媒体播放
  • 触发强制动画
  • 集成第三方DOM库

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

二、勿过度使用 Refs

让更高的组件层级拥有这个state,是更恰当的

==question==:更高层级的组件是指 父组件 还是 子组件?

注意:React16.3版本引入了React.createRef() API,如果在使用较早版本的React,推荐使用回调形式的refs

三、创建 Refs

refs是使用React.createRef()创建的,并通过 ref 属性附加到React元素

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

React 会在组件挂载时给 current 属性传入 DOM 元素,并在组件卸载时传入 null 值。ref 会在 componentDidMount 或 componentDidUpdate 触发前更新

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>
    );
  }
}
  • 为class 组件添加 Ref
class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

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

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}
  • Refs与函数组件
不能在函数组件上使用 ref 属性,因为它们没有实例
可以在函数组件内部使用 ref 属性,只要它指向一个 DOM 元素或 class 组件

五、将 DOM Refs 暴露给父组件

  1. 在极少数的情况下,可能希望在父组件中引用子节点的 DOM 节点。通常不建议这样子做,因为它会打破组件的封装,但它偶尔可用于触发焦点或测量子DOM节点的大小或位置
  2. 虽然可以向子组件添加 ref,但这不是一个理想的解决方案,因为你只能获取实例而不是 DOM 节点
  3. 16.3 或更高版本的 React 推荐使用 ==ref转发==。Ref 转发使组件可以像暴露自己的 ref 一样暴露子组件的 ref
  4. 可能的话,不建议暴露DOM节点

六、回调 Refs

react支持另一种设置 refs 的方式,称为“回调refs”,它能帮助你更精细地控制何时 refs 被设置和接触

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);

    this.textInput = null;

    this.setTextInputRef = element => {
      this.textInput = element;
    };

    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      if (this.textInput) this.textInput.focus();
    };
  }

  componentDidMount() {
    // 组件挂载后,让文本框自动获得焦点
    this.focusTextInput();
  }

  render() {
    // 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
    // 实例上(比如 this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}
        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

以上是关于了解一下refs的主要内容,如果未能解决你的问题,请参考以下文章

极智开发 | 讲解 React 组件三大属性之三:refs

调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段

Golang Functional Options 来了解一下?

java后端开发每天遇到的jsp,了解一下

C++ 左值引用

Spring中Bean的命名问题及ref和idref之间的区别