react - 06.useRef

52 阅读2分钟

1.useRef的作用:

useRef返回一个可变的ref对象,该对象只有一个current属性,初始值为传入的参数,并且返回的reg对象在组件的整个生命周期内保持不变

useRef可以获取子组件或者dom节点的实例对象

存储渲染周期之间的共享数据

2.获取子dom节点的实例:

import { useRef } from 'react'
const App = () => {
  const inputRef = useRef<HTMLInputElement>(null)
  const handleClick = () => {
    inputRef.current?.focus()
  }
  return (
    <>
      <div>
        <input type="text" ref={inputRef} />
        <button onClick={handleClick}>click</button>
      </div>
    </>
  )
}
export default App
import {useRef} from 'react'
const App = () => {
  const eleRef = useRef<HTMLDivElement>(null)
  const handleRef = () => {
    (eleRef.current?.style as any).backgroundColor = "#f00";
    (eleRef.current?.style as any).color = "#fff";
  }
  return (
    <div>
      <h1 ref={eleRef}>hello</h1>
      <button onClick={handleRef}>change</button>
    </div>
  )
}
export default App

3.获取函数组件ref:

假设我们新建一个hello的组件,并且在App父组件中引用

Hello.tsx:

const Hello = () => {
    return (
        <div>
            <h1>hello</h1>
        </div>
    )
}
export default Hello

App.tsx:

import { useRef } from 'react'
import Hello from './components/Hello';
const App = () => {
  const getDom = useRef<HTMLDivElement>(null)
  return (
    <div>
      <Hello ref={getDom} />
    </div>
  )
}
export default App

这个时候,控制台会报错:

微信图片_20230519003351.png

警告:不能给函数组件赋值。尝试访问此引用将失败。你是想用React.forwardRef()吗?

函数组件是不能绑定ref的,因为ref是通过this获取的,因为函数组件的this是undefined,也就是没有ref这个属性,所以不能绑定。但是类组件可以

如果想要实现获取子组件的dom节点,那么这个时候我们就要用到 forwardRef()

例子:

Hello.tsx:

import { forwardRef } from 'react'
const Hello = forwardRef((props:any,eleRef:any) => {
    console.log(props)
    return (
        <div>
            <input placeholder={props.placeholder} type="text" ref={eleRef} />
        </div>
    )
})
export default Hello

App.tsx:

import { useRef } from 'react'
import Hello from './components/Hello';
const App = () => {
  const getDom = useRef<HTMLDivElement>(null)
  const handleDom = () => {
    console.log(getDom)
    getDom.current?.focus();
  }
  return (
    <div>
      <Hello placeholder={'请输入'} ref={getDom} />
      <button onClick={handleDom}>getDom</button>
    </div>
  )
}
export default App

4.useRef注意事项:

组件的每次渲染,useRef返回值都不变

ref.current发生变化并不会造成重新渲染

不可在render函数中更新ref.current的值

如果给一个组件设定了ref属性,但是对应的值却不是有useRef创建的,那么实际运行中会收到React的报错,无法正常渲染

ref.current不可作为其他Hooks的依赖项,因为ref是可变的,不会使界面再次渲染(ref.current的值发生变更并不会造成重新渲染,React也不会跟踪ref.current的变化)