useRef和useContext
面试速答
- 以下内容以 React 18 为准。
useRef和useContext都是常用 Hook,但解决的问题完全不同:useRef:保存一个跨 render 持续存在、修改后不触发重渲染的可变引用useContext:读取最近一层 Provider 提供的上下文值
useRef 怎么理解
1. 本质是一个稳定对象
const ref = useRef<HTMLDivElement | null>(null)
返回值通常形如:
{ current: ... }
这个对象在组件整个生命周期里通常是同一个引用。
2. 常见用途
- 获取 DOM 节点
- 保存定时器 ID
- 保存上一次值
- 让长期存在的回调拿到最新数据
3. 重要特征
改 ref.current 不会触发重渲染,所以它适合存“不会直接驱动 UI 的值”。
useContext 怎么理解
1. 作用是跨层传值
const theme = useContext(ThemeContext)
它会读取当前组件向上最近的 ThemeContext.Provider 的 value。
2. 典型场景
- 主题
- 多语言
- 当前用户信息
- 局部状态容器
3. 重要特征
当 Provider 的 value 变化时,消费这个 Context 的组件会重新渲染。
所以 Context 不是“性能优化工具”,而是“共享数据通道”。
两者区别
| 维度 | useRef | useContext |
|---|---|---|
| 解决问题 | 保存稳定可变引用 | 跨层读取共享值 |
| 修改后是否触发重渲染 | 否 | Provider 值变时会 |
| 常见用途 | DOM、定时器、最新值 | 主题、用户信息、全局/局部共享状态 |
标准答法
问:useRef 和 useContext 的区别是什么?
答:useRef 是保存稳定可变容器,不参与响应式更新;useContext 是读取上下文共享值,Provider 值变化时会驱动消费组件更新。
易错点
- 用
useRef存本该驱动 UI 的状态。 - 认为
useContext天然高性能,结果把一个大对象放进去导致大范围重渲染。 - 混淆“共享数据”和“可变引用”。
速记要点
useRef:存引用,不触发 render。useContext:读共享值,Provider 变会触发消费方更新。- 两者根本不是同一类能力。