logo

useRef

2026年3月20日 |
ReactHooks

1. 简介

useRef是React中常用的Hook之一,常用于保存数据、获取dom、引用组件。它和useState一样是可以长期保存值的一个引用容器。它和useState的区别就是它存储的值更改时不会触发组件的渲染。

useState 与 useRef 对比

特性useStateuseRef
修改值时触发组件重新渲染不触发渲染
组件重新渲染时获取的是最新状态值获取的是之前保存的值(.current)
主要用途管理会影响 UI 显示的数据保存 DOM 引用、上一轮值、定时器等
是否适合作为依赖适合(值变化会触发 effect)通常不适合(对象引用不变)

2. 保存数据

需求:我们现在有一个按钮,当我点击之后清除上一次的定时器,重新开启一个定时器。每次只有一个定时器存在。以下是我们的代码实现:

function App() {
  let timer;
  const handleClick = () => {
    // 本次的timer和上一次的timer不是一个变量
    clearInterval(timer);
    timer = setInterval(() => {}, 1000);
  };
}

以上代码虽然看上去没有问题,但是如果组件重新渲染,是不会清除之前定时器的。当组件重新渲染的时候,会生成一个新的timer,本次的timer和上一个timer不是一个变量。

function App() {
  let timer = useRef(null);
  const handleClick = () => {
    clearInterval(timer.current);
    timer = setInterval(() => {}, 1000);
  };
}

3. 获取DOM

当我们需要获取dom元素的时候,我们可以使用useRef来保存dom元素的引用。例如:

import { useRef } from "react";
export default function App() {
const h1Ref = useRef(null);
const handleClick = () => {
console.log(h1Ref.current); // 获取操作dom元素的引用
h1Ref.current.style.color = "skyblue"; // 改变字体颜色
h1Ref.current.style.backgroundColor = "yellow"; // 改变背景颜色
};
return (
<h1 ref={h1Ref} onClick={handleClick}>
Hello World
</h1>
);
}

当我们点击h1元素的时候,会改变h1元素的字体颜色和背景颜色。

4. 引用组件

需求:我们有一个模态框子组件,这个子组件中有显示和隐藏的方法。当父组件想要调用子组件的显示和隐藏方法时,我们可以使用useRef来引用子组件。

父组件:

import { useRef } from "react";
export default function App() {
  const modalRef = useRef(null);
  return (
    <>
      <Modal ref={modalRef} />
      <button onClick={() => modalRef.current?.showModal()}>显示</button>
    </>
  );
}

子组件:

import { useImperativeHandle, useState } from "react";
export function Modal(props, ref) {
  // 配置组件的ref,使父组件可以调用子组件的方法
  // 这里我们只暴露了showModal方法,其他方法可以不暴露
  useImperativeHandle(ref, () => ({
    showModal: showModal,
  }));
  const [show, setShow] = useState(false);
  const showModal = () => {
    setShow(true);
  };
  const hideModal = () => {
    setShow(false);
  };
  return <h2>模态框</h2>;
}

这样父组件就可以调用子组件的showModal方法了。