文章目录
- 前言
-
- [一 useRef 的核心原理](#一 useRef 的核心原理)
-
- [1.1 为什么需要 useRef?](#1.1 为什么需要 useRef?)
- [1.2 基本语法](#1.2 基本语法)
- [二、React 19 中 useRef 的常见用法](#二、React 19 中 useRef 的常见用法)
-
- [2.1 访问 DOM 元素](#2.1 访问 DOM 元素)
- [2.2 保存跨渲染的数据](#2.2 保存跨渲染的数据)
- [三、React 19 中的改进](#三、React 19 中的改进)
-
- [ref 作为一个属性](#ref 作为一个属性)
- 案例演示(触发子组件焦点事件)
- 注意
- 总结
前言
在 React 的世界里,useRef
是一个既简单又强大的 Hook,它常常被用于访问 DOM 元素、保存不可变数据或管理组件的生命周期行为。随着 React 19 的发布,useRef
的使用场景和最佳实践也得到了进一步强化。本文将结合 React 19 的特性,深入探讨 useRef
的核心用法、常见误区以及实战技巧。
一 useRef 的核心原理
useRef
是 React 提供的一个内置 Hook,用于创建一个可变的 ref
对象。其返回值是一个包含 current
属性的对象,该属性在整个组件的生命周期中保持不变。
1.1 为什么需要 useRef?
- 访问 DOM 元素 :在函数组件中,
useRef
是获取 DOM 节点的标准方式。 - 保存跨渲染的数据 :
useRef
的current
属性不会因组件的重新渲染而改变,适合存储不需要触发重渲染的数据。 - 管理副作用 :结合
useEffect
,useRef
可以用于控制副作用的执行时机。
1.2 基本语法
c
import { useRef } from 'react';
function MyComponent() {
const myRef = useRef(initialValue);
// 使用 myRef.current 访问或修改值
return <div ref={myRef}>Hello, World!</div>;
}
二、React 19 中 useRef 的常见用法
2.1 访问 DOM 元素
这是 useRef
最经典的用法。通过将 ref
属性绑定到 DOM 元素上,可以直接操作该元素。
示例:聚焦输入框
c
import { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current?.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Type something..." />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
}
2.2 保存跨渲染的数据
useRef
的 current
属性不会因组件的重新渲染而改变,因此可以用来存储一些不需要触发重渲染的数据,比如计时器 ID 或事件监听器。
示例:记录按钮点击次数
c
import { useRef } from 'react';
function ClickCounter() {
const clickCountRef = useRef(0);
const handleClick = () => {
clickCountRef.current += 1;
console.log(`Button clicked ${clickCountRef.current} times`);
};
return <button onClick={handleClick}>Click Me</button>;
}
三、React 19 中的改进
之前我们在18版本的时候你要传递ref给外部,需要借助forwardRef,现在到了react 19不需要了,你直接以属性的方式进行传递。
ref 作为一个属性
从 React 19 开始,你现在可以在函数组件中将 ref
作为 prop 进行访问:
c
function MyInput({placeholder, ref}) {
return <input placeholder={placeholder} ref={ref} />
}
//...
<MyInput ref={ref} />
新的函数组件将不再需要 forwardRef
,我们将发布一个 codemod 来自动更新你的组件以使用新的 ref
prop。在未来的版本中,我们将弃用并移除 forwardRef
。
案例演示(触发子组件焦点事件)
c
import { useRef } from "react";
const Child = ({ ref }: { ref: React.Ref<HTMLInputElement> }) => {
return (
<div>
<input type="text" ref={ref} />
</div>
);
};
const App = () => {
const childRef = useRef<HTMLInputElement>(null);
const handler = () => {
childRef.current?.focus();
};
return (
<div>
<button onClick={() => handler()}>点击</button>
<Child ref={childRef} />
</div>
);
};
export default App;

注意
- 在类组件中,
ref
不作为 props 传递,因为它们引用的是组件实例。这意味着,如果你在类组件中需要访问ref
,你需要使用React.forwardRef
或者React.createRef
。 - useRef的值不能作为useEffect等其他hooks的依赖项,因为它并不是一个响应式状态
- 组件在重新渲染的时候,useRef的值不会被重新初始化。
总结
useRef 是 React 中一个简单却强大的 Hook,它在 React 19 中依然保持着其核心价值。通过掌握 useRef 的基本用法、高级技巧以及最佳实践,你可以更高效地开发 React 应用,避免常见的性能问题和代码混乱。