一、前言
在 React 中,useRef 和 useState 是两个常用的 Hook,它们都可以用来存储数据,但用途和更新机制有明显差异。理解它们的使用场景区别,有助于我们写出更高效、可维护的组件代码。
二、useState 的特点与使用场景
1. 特点
-
用于存储 会影响组件渲染的数据。
-
当状态发生变化时,React 会重新渲染组件。
-
适合处理 UI 交互状态,如表单输入、计数器、切换状态等。
2. 使用示例
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return (
<div>
<p>当前计数:{count}</p>
<button onClick={increment}>增加</button>
</div>
);
}
export default Counter;
在这个例子中,每次点击按钮,count 状态变化,组件会重新渲染,页面显示的数字也会更新。
3. 使用场景总结
-
需要触发 组件重新渲染 的数据。
-
依赖于 UI 更新的状态,例如:表单输入值、开关状态、计数器等。
三、useRef 的特点与使用场景
1. 特点
-
用于存储 不需要触发渲染的数据。
-
useRef返回一个可变对象{ current: ... },可以直接修改current属性。 -
常用于:
-
访问 DOM 元素
-
保存定时器、外部变量、上一次渲染的值
-
2. 使用示例
2.1 访问 DOM 元素
javascript
import React, { useRef } from 'react';
function InputFocus() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>聚焦输入框</button>
</div>
);
}
export default InputFocus;
这里使用 useRef 获取 DOM 节点,并操作它,而不需要触发组件重新渲染。
2.2 保存不触发渲染的变量
javascript
import React, { useRef, useState } from 'react';
function Timer() {
const countRef = useRef(0);
const [ignored, setIgnored] = useState(0);
const incrementRef = () => {
countRef.current += 1;
console.log(countRef.current);
};
const forceRender = () => setIgnored(ignored + 1);
return (
<div>
<button onClick={incrementRef}>增加 ref 计数(不刷新)</button>
<button onClick={forceRender}>强制刷新</button>
</div>
);
}
export default Timer;
countRef 的更新不会触发组件渲染,而 forceRender 通过 useState 强制刷新组件。
3. 使用场景总结
-
不依赖于 UI 渲染的状态。
-
需要 在多次渲染间保存数据,但不想每次都触发渲染。
-
操作 DOM 或保存定时器、上一次的值、外部对象等。
四、useState 与 useRef 的对比
| 特性 | useState | useRef |
|---|---|---|
| 更新是否触发渲染 | 是 | 否 |
| 保存数据的生命周期 | 组件整个生命周期 | 组件整个生命周期 |
| 是否可访问 DOM | 否 | 是 |
| 使用场景 | UI 状态、交互数据 | DOM 引用、缓存数据、定时器、跨渲染变量 |
总结关键点:
-
需要渲染更新 → 用 useState
-
不需要渲染更新 → 用 useRef
五、实际开发建议
-
UI 状态优先用
useState,保持 React 哲学和响应式特性。 -
避免滥用
useRef保存状态,否则可能导致组件不刷新,UI 与数据不同步。 -
操作 DOM、保存定时器、跨渲染变量 使用
useRef,既高效又安全。
六、结语
掌握 useState 和 useRef 的使用场景区别,是写高效 React 组件的关键。合理选择 Hook,不仅能减少不必要的渲染,还能让代码逻辑更清晰、更易维护。