React学习笔记[11]✨~关于React18中如何使用ref👻

338 阅读2分钟

我正在参加「掘金·启航计划」

一、使用ref获取DOM

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

管理焦点、文本选择或者媒体播放;

触发强制动画;

集成第三方DOM库;

在React中可以通过refs获取DOM,目前有三种方式来创建refs(其中方式一已不再推荐)

方式一:传入字符串(注意:官方不推荐这种方式)

  1. 首先在React元素上绑定一个ref字符串
  2. 然后通过this.refs.xx来获取即可

此方式官方不推荐使用,此方式已经过时并在未来版本会被移除

import React, { PureComponent } from 'react'

export class App extends PureComponent {

  getDOM() {
    console.log(this.refs.hello)
  }

  render() {
    return (
      <div>
        <h2 ref="hello">Hello World</h2>
        <button onClick={e => this.getDOM()}>获取DOM</button>
      </div>
    )
  }
}

export default App

方式二:传入一个对象

  1. 提前通过createRef() 创建好ref对象,如titleRef
  2. 将创建好的对象绑定到React元素上
  3. 通过this.titleRef.current来获取该DOM元素
import React, { PureComponent, createRef } from 'react'

export class App extends PureComponent {
  constructor() {
    super()
    this.titleRef = createRef()
  }

  getDOM() {
    console.log(this.titleRef.current)
  }

  render() {
    return (
      <div>
        <h2 ref={this.titleRef}>Hello World</h2>
        <button onClick={e => this.getDOM()}>获取DOM</button>
      </div>
    )
  }
}

export default App

方式三:传入一个函数

传入一个回调函数,当元素被选然后该回调函数会被执行,并将DOM元素传入

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

export class App extends PureComponent {
  constructor() {
    super()
    this.titleEl = null
  }

  getDOM() {
    console.log(this.titleEl)
  }

  render() {
    return (
      <div>
        <h2 ref={el => this.titleEl = el}>Hello World</h2>
        <button onClick={e => this.getDOM()}>获取DOM</button>
      </div>
    )
  }
}

export default App

二、使用ref获取类组件实例

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

当ref属性用于HTML元素时,构造函数中使用React.createRef()创建的ref接收底层DOM元素作为其current属性值;

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

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


class HelloWorld extends PureComponent {
  test() {
    console.log("test...")
  }

  render() {
    return <h1>Hello World</h1>
  }
}

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

    this.helloRef = createRef()
  }

  getComponent() {
    console.log(this.helloRef.current)
    this.helloRef.current.test() // test...
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.helloRef}/>
        <button onClick={e => this.getComponent()}>获取组件实例</button>
      </div>
    )
  }
}

export default App

三、使用ref获取函数组件的DOM

函数组件是没有组件实例的,所以无法通过ref获取函数组件的实例, 但是有些时候可能想要获取函数组件中的某个DOM元素

此时可以通过React.forwardRef,其次就是通过hooks(后续讲解)

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


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


export class App extends PureComponent {
  constructor() {
    super()
    this.helloRef = createRef()
  }

  getComponent() {
    console.log(this.helloRef.current)
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.helloRef}/>
        <button onClick={e => this.getComponent()}>获取组件实例</button>
      </div>
    )
  }
}

export default App