• React.createRef


    Refs提供了一个访问在render方法中生成的DOM节点或React元素

    何时使用?

    • 处理焦点,文本选择,媒体播放
    • 触发命令式的动画
    • 与第三方dom库交互
      ps:避免在任何可以使用申明式的时候使用refs
      For example, instead of exposing open() and close() methods on a Dialog component, pass an isOpen prop to it.

    如何使用?

    创建Refs

    Ref通过使用React.createRef() 以及在React elements 上添加ref 属性创建,在构建组件时,ref通常被赋值给instance属性,以便在整个组件中引用它们。

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.myRef = React.createRef();
      }
      render() {
        return <div ref={this.myRef} />;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    访问refs

    当ref在render方法中传递给了一个element后,这个节点的引用在ref的current属性上可访问了

    const node = this.myRef.current;
    
    • 1

    其中,ref的值根据node的类型有些许不同:

    • 当ref属性被用在HTML元素上时,那么ref就接受DOM元素作为current属性
    • 当ref属性被用在自定义的类组件时,ref就接受组件的mounted 实例作为current属性
    • 不可以将ref属性用在函数组件中
    使用ref存储dom节点的引用
    class CustomTextInput extends React.Component {
      constructor(props) {
        super(props);
        // create a ref to store the textInput DOM element
        this.textInput = React.createRef();
        this.focusTextInput = this.focusTextInput.bind(this);
      }
    
      focusTextInput() {
        // Explicitly focus the text input using the raw DOM API
        // Note: we're accessing "current" to get the DOM node
        this.textInput.current.focus();
      }
    
      render() {
        // tell React that we want to associate the  ref
        // with the `textInput` that we created in the constructor
        return (
          <div>
            <input
              type="text"
              ref={this.textInput} />
            <input
              type="button"
              value="Focus the text input"
              onClick={this.focusTextInput}
            />
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    React will assign the current property with the DOM element when the component mounts, and assign it back to null when it unmounts. ref updates happen before componentDidMount or componentDidUpdate lifecycle methods.
    当组件挂载的时候,React将把DOM元素赋值给current属性,当组件卸载的时候ref为null,ref 在componentDidMount和componentDidUpdate两个生命周期方法执行时发生更新。

    使用ref存储类组件的引用

    如果我们想模拟上面CustomTextInput组件一加载就触发点击事件,可以在父组件中使用ref

    class AutoFocusTextInput extends React.Component {
      constructor(props) {
        super(props);
        this.textInput = React.createRef();
        this.myRef=React.createRef();
      }
    
      componentDidMount() {
        this.textInput.current.focusTextInput();
        this.myRef.current.scrollIntoView()
      }
    
      render() {
        return (
          <CustomTextInput ref={this.textInput} />
          <div ref={this.myRef}></div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Note that this only works if CustomTextInput is declared as a class:
    注意:以上只有在CustomTextInput被申明为一个类的时候才有效。

    不可以在函数组件上使用ref
    function MyFunctionComponent() {
      return <input />;
    }
    
    class Parent extends React.Component {
      constructor(props) {
        super(props);
        this.textInput = React.createRef();
      }
      render() {
        // 不可以这样!!!!
        return (
          <MyFunctionComponent ref={this.textInput} />
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其他解决办法:使用forwardRef或者将函数组件改成类组件,当然你也可以在函数内部使用ref

    callback refs

    • React 16.3之前使用callback refs:给了关于ref set 和 unset 更精细的控制

    参考文档

    https://reactjs.org/docs/refs-and-the-dom.html

  • 相关阅读:
    谷歌、微软、Meta?谁才是 Python 最大的金主?
    jumpserver堡垒机/跳板机
    【ceph】ceph集群中使用多路径(Multipath)方法
    『昆仑天工』4款AI产品开源!提供API对接!
    什么情况下适合使用静态路由?什么情况下适合使用动态路由?
    HBase2.x(四)HBase API 创建连接
    你真的了解IP地址吗?
    2022数学建模国赛降至,整理了一些很不错的在线网站分享一下
    React TypeScript 样式报错
    .net 杂谈之二
  • 原文地址:https://blog.csdn.net/qq_38397338/article/details/126449897