前端小白学 React 框架(十二)

101 阅读2分钟

Ref

ref的使用场景

在React的开发模式中,通常情况下不需要、也不建议直接操作DOM原生,但是某些特殊的情况,确实需要获取到DOM进行某些操作:

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

ref获取DOM元素的三种方式

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

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

在react元素上放入一个ref字符串

import React, { PureComponent } from 'react'

export default class App extends PureComponent {
  getNativeDOM() {
    // 在react元素上放入一个ref字符串
    console.log(this.refs.haha);
  }

  render() {
    return (
      <div>
        <h1 ref="haha">ref获取DOM</h1>
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

效果如下:

屏幕录制2023-05-21 23.35.22.gif

创建ref对象

import React, { PureComponent, createRef } from 'react'

export default class App extends PureComponent {
  constructor() {
    super();

    this.titleRef = createRef();
  }
  getNativeDOM() {
    // 用createRef创建ref对象,并绑定到元素上
    console.log(this.titleRef.current);
  }

  render() {
    return (
      <div>
        <h1 ref="haha">ref获取DOM</h1>
        <h2 ref={this.titleRef}>ref获取DOM</h2>
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

效果如下:

屏幕录制2023-05-21 23.42.34.gif

⭕️ 推荐这种方式

回调函数的形式

import React, { PureComponent, createRef } from 'react'

export default class App extends PureComponent {
  constructor() {
    super();

    this.titleRef = createRef();
  }
  getNativeDOM() {
    // 回调函数的形式
    console.log(this.title);
  }

  render() {
    return (
      <div>
        <h1 ref="haha">ref获取DOM</h1>
        <h2 ref={this.titleRef}>ref获取DOM</h2>
        <h3 ref={el => this.title = el}>ref获取DOM</h3>
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

效果如下:

屏幕录制2023-05-21 23.46.33.gif

ref获取类组件实例

采用获取元素的第二种方法:

import React, { PureComponent, createRef } from 'react'

class HelloWorld extends PureComponent {
  render() {
    return <h1>Hello World</h1>
  }
}

export default class App extends PureComponent {
  constructor() {
    super();

    this.helloWorldRef = createRef();
  }
  getNativeDOM() {
    console.log(this.helloWorldRef.current);
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.helloWorldRef} />
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

效果如下:

屏幕录制2023-05-22 00.03.53.gif

ref获取函数式组件实例

在前面我们学习ref时讲过,ref不能应用于函数式组件,因为函数式组件没有实例,所以不能获取到对应的组件对象但是,在开发中我们可能想要获取函数式组件中某个元素的DOM,这个时候我们应该如何操作呢?

  • 直接传入ref属性(❌ 错误的做法)
  • 通过forwardRef高阶函数(⭕️ 正确的做法),后面我们也会学习 hooks 中如何使用ref
import React, { PureComponent, createRef, forwardRef } from 'react'

const HelloWorld = forwardRef(function (props, ref) {
  return (
    <div>
      <h1 ref={ref}>Hello World</h1>
      <h2>hahaha</h2>
    </div>
  )
})

export default class App extends PureComponent {
  constructor() {
    super();

    this.helloWorldRef = createRef();
  }
  
  getNativeDOM() {
    console.log(this.helloWorldRef.current);
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.helloWorldRef} />
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

效果如下:

屏幕录制2023-05-22 00.12.14.gif

写在最后

如果大家喜欢的话可以收藏本专栏,之后会慢慢更新,然后大家觉得不错可以点个赞或收藏一下 🌟。

博客内的项目源码在react-app分支,大家可以拷贝下来。