React ref 和 JS 对象的区别
✅ React 中的 ref
是什么?
在 React 中,ref
(Reference) 是用来:
在不通过 state 的情况下,引用 DOM 或保存某个可变值 的机制。
🆚 React ref
和普通 JS 对象的区别
特性 | React ref | 普通 JS 对象 {} |
---|---|---|
是否响应式 | ❌ 不是响应式(修改后不会引发 re-render) | ❌ 同样不是 |
用于持久化跨渲染值 | ✅ 是(值在多次 render 中保持不变) | ❌ 不会(组件每次 render 都重新构造) |
能否挂载到 DOM 元素 | ✅ 可以通过 ref={myRef} 挂载 DOM | ❌ 不行 |
生命周期内是否共享 | ✅ 是 | ❌ 否,每次 render 都会新建 |
📌 示例:普通 JS 对象的问题
function MyComponent() {const counter = { current: 0 };const handleClick = () => {counter.current++;console.log(counter.current);};return <button onClick={handleClick}>Click</button>;
}
问题: 每次 render,counter
都是新对象,值不会保留。
✅ 使用 useRef
正确方式
import { useRef } from "react";function MyComponent() {const counter = useRef(0); // 保持跨 render 持久const handleClick = () => {counter.current++;console.log(counter.current);};return <button onClick={handleClick}>Click</button>;
}
useRef()
返回一个{ current: ... }
对象。- 这个对象在整个组件生命周期内不会变化(就像是“盒子”)。
- 改变
ref.current
不会触发组件重新渲染。
✅ 用途总结
用途 | 示例说明 |
---|---|
💡 持久保存可变数据(跨渲染) | 比如计时器 ID、上次滚动位置、旧的 props 等 |
🎯 获取真实 DOM 节点 | <div ref={myRef} /> 获取 DOM |
🧠 存储函数引用 | 防止闭包陷阱、绑定旧变量 |
🔥 不想触发渲染的缓存值 | 用来做性能优化 |
✅ 示例:获取 DOM 节点
function InputFocus() {const inputRef = useRef(null);const handleClick = () => {inputRef.current.focus(); // 直接操作 DOM};return (<><input ref={inputRef} /><button onClick={handleClick}>Focus</button></>);
}
❗注意事项
- 修改
ref.current
不会触发组件更新(不像useState
)。 - 不要试图监听
ref.current
的变化,ref 不是响应式系统。 - 不适合替代 state 做 UI 展示用途。
✅ 总结一句话
🔧
useRef
是一个不会因为组件重新渲染而重置的可变容器,适合保存 DOM 引用或临时变量。