跳到主要内容

useRef和useContext

面试速答

  • 以下内容以 React 18 为准。
  • useRefuseContext 都是常用 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.Providervalue

2. 典型场景

  • 主题
  • 多语言
  • 当前用户信息
  • 局部状态容器

3. 重要特征

当 Provider 的 value 变化时,消费这个 Context 的组件会重新渲染。

所以 Context 不是“性能优化工具”,而是“共享数据通道”。

两者区别

维度useRefuseContext
解决问题保存稳定可变引用跨层读取共享值
修改后是否触发重渲染Provider 值变时会
常见用途DOM、定时器、最新值主题、用户信息、全局/局部共享状态

标准答法

问:useRefuseContext 的区别是什么?

答:useRef 是保存稳定可变容器,不参与响应式更新;useContext 是读取上下文共享值,Provider 值变化时会驱动消费组件更新。

易错点

  • useRef 存本该驱动 UI 的状态。
  • 认为 useContext 天然高性能,结果把一个大对象放进去导致大范围重渲染。
  • 混淆“共享数据”和“可变引用”。

速记要点

  • useRef:存引用,不触发 render。
  • useContext:读共享值,Provider 变会触发消费方更新。
  • 两者根本不是同一类能力。