useRef与组件内普通变量的区别解析及选型建议
React中useRef与组件内部普通变量的区别及选择指南
你的理解纠正
首先要明确:你的理解存在偏差。组件每次重新渲染时,普通变量会被重新初始化,不会保留上一次渲染的值;而useRef创建的引用对象,其.current属性会在组件整个生命周期内持续保留值,并且修改.current不会触发组件重渲染。
举个简单例子对比:
function Example() { // 普通变量:每次渲染都会重置为0 let normalVar = 0; // useRef变量:组件生命周期内始终保留同一个引用,.current值持续保留 const refVar = useRef(0); const handleClick = () => { normalVar++; refVar.current++; console.log('普通变量:', normalVar); console.log('useRef变量:', refVar.current); }; console.log('组件渲染,普通变量:', normalVar); console.log('组件渲染,useRef变量:', refVar.current); return <button onClick={handleClick}>点击计数</button>; }
点击按钮后,控制台会显示:每次组件渲染时普通变量都是0,而useRef的.current会持续累加。
核心区别总结
- 生命周期内的持续性:
- 普通变量:仅存在于当前渲染周期,组件重新渲染时会被重新声明并初始化,之前的值完全丢失。
- useRef:创建的引用对象在组件挂载时生成,直到组件卸载才会销毁,
.current属性可以一直存储数据。
- 重渲染触发:
- 普通变量:修改它不会触发重渲染,但因为每次渲染都会重置,所以实际无法在渲染间共享状态。
- useRef:修改
.current不会触发组件重渲染,这是它和useState的关键区别之一。
二者的选择场景
优先用普通变量的情况
- 只需要在当前渲染周期内临时使用的值,比如渲染时的临时计算变量、事件处理函数内部的局部变量。
- 不需要在组件多次渲染间保留的数据,比如渲染列表时的循环计数器、临时的格式化结果。
优先用useRef的情况
- 需要在组件多次渲染间保留状态,但又不想触发重渲染的场景:
- 存储DOM元素引用(最常见的用法,比如获取输入框焦点):
const inputRef = useRef(null); const focusInput = () => inputRef.current.focus(); return <input ref={inputRef} />; - 存储定时器ID,方便后续清除:
const timerRef = useRef(null); useEffect(() => { timerRef.current = setInterval(() => { /* 定时任务 */ }, 1000); return () => clearInterval(timerRef.current); }, []); - 保存上一次渲染的props或state值,用于对比变化:
const prevCountRef = useRef(); useEffect(() => { prevCountRef.current = count; }, [count]); // 可以通过prevCountRef.current获取上一次的count值 - 存储不需要触发重渲染的状态数据,比如一些UI无关的统计值、缓存的计算结果。
- 存储DOM元素引用(最常见的用法,比如获取输入框焦点):
内容的提问来源于stack exchange,提问作者markcalendario
相关产品推荐
相关产品推荐

