React通过refs获取DOM

544 阅读2分钟

在某些特殊的情况下,我们需要获取到原生DOM元素进行某些操作。

那么如何创建refs来获取对应的DOM呢?目前有三种方式:

  • 方式一:传入字符串(已废弃,不建议使用

    • 使用时通过this.refs.传入的字符串格式获取对应的元素
    getNativeDom() {
        // 在React元素上绑定一个ref字符串
        console.log(this.refs.why); // 会打印DOM元素,<h2>hello world</h2>
      }
      render() {
        return (
          <div>
            <h2 ref='why'>hello world</h2>
            <button onClick={(e) => this.getNativeDom()}>获取DOM</button>
          </div>
        );
      }
    
  • 方式二:传入一个对象

    • 对象是通过React.createRef()方式创建出来的;
    • 使用时获取到创建的对象其中有一个current属性就是对应的元素
    constructor() {
        super();
        this.titleRef = createRef();
      }
      getNativeDom() {
          // 提前创建好ref对象,createRef(),将创建好的对象绑定过到元素
        console.log(this.titleRef.current); // <h2>hello React</h2>
      }
      render() {
        return (
          <div>
            <h2 ref={this.titleRef}>hello React</h2>
            <button onClick={(e) => this.getNativeDom()}>获取DOM</button>
          </div>
        );
      }
    
  • 方式三:传入一个函数

    • 该函数会在DOM被挂载时进行回调,这个函数会传入一个元素对象,我们可以自己保存;
    • 使用时,直接拿到之前保存的元素对象即可;
    constructor() {
        super();
        this.title = null;
      }
      getNativeDom() {
        console.log(this.title); // 打印,<h2>你好,李银河</h2>
      }
      render() {
        return (
          <div>
            <h2 ref={e=>this.title=e}>你好,李银河</h2>
            <button onClick={(e) => this.getNativeDom()}>获取DOM</button>
          </div>
        );
      }
    

    用refs来获取组件

    • 当ref属性用于自定义类组件时,ref对象接收组件的挂载实例作为其current属性;

      // HelloWorld组件
      class HelloWorld extends PureComponent {
          test(){
              console.log('我是helloWorld组件');
          }
          render() {
            return (
              <div>
                <h2>hello world Page</h2>
              </div>
            );
          }
        }
      // 父组件
      ......
      getCompt(){
          console.log(this.componentEl.current); // 打印HelloWorld组件
          this.componentEl.current.test(); // 还可以调用子组件中的方法
        }
        render() {
          return (
            <div>
              <HelloWorld ref={this.componentEl}></HelloWorld>
              <button onClick={(e) => this.getCompt()}>获取组件</button>
            </div>
          );
        }
      
    • 函数式组件式没有实例的,所以不能在函数式组件上使用ref属性;

      • 可以通过forwardRef高阶函数实现
      // HelloWorld组件
      const HelloWorld = forwardRef(function (props, ref) { // 函数的第二个参数就是传入的ref
        return (
          <div>
            <h2 ref={ref}>hello world Page</h2> // 把ref绑定到组件内部的某一个元素
          </div>
        );
      });
      // 父组件
      ......
      getCompt(){
          console.log(this.componentEl.current); // 打印<h2> hello world Page </h2>
        }
        render() {
          return (
            <div>
              <HelloWorld ref={this.componentEl}></HelloWorld>
              <button onClick={(e) => this.getCompt()}>获取组件</button>
            </div>
          );
        }