useContext 有什么使用场景和性能风险?
满分答案#
useContext 用于跨层级组件共享数据,解决 props 逐层传递问题;但只要 context 的 value 变化,所有使用该 context 的组件都会全部重渲染,容易造成大面积无效渲染,这是最大的性能风险。
一、useContext 适用场景#
- 全局通用状态 主题(亮色/暗色)、语言、用户信息、全局配置
- 多层级传值 爷→父→子→孙,不想一层层 props 透传
- 组件库内部状态共享 表单、弹窗、步骤条等跨组件通信
二、useContext 最大性能风险#
风险:value 一变,全体消费者重渲染!#
- 只要
Provider的value改变 - 所有用到 useContext(MyContext) 的组件都会重渲染
- 即使组件只用到一小部分数据,也会被迫渲染
- 项目越大,性能浪费越严重
根本原因#
React 对 value 做引用比较(===)
每次父组件渲染,若直接写:
<MyContext.Provider value={{ a:1, b:2 }}>jsx会创建新对象 → 引用变化 → 所有消费者重渲染。
三、如何避免性能问题?#
1. 拆分 Context#
把经常变和不经常变的状态分开存放
<UserContext.Provider value={user}>
<ThemeContext.Provider value={theme}>jsx2. 用 useMemo 缓存 value#
const value = useMemo(() => ({ user, theme }), [user, theme]);jsx3. 组件结合 memo + 只取需要的值#
让组件只在真正用到的数据变化时才渲染
4. 复杂状态用状态库#
Redux、Zustand、Jotai 等,它们可以精准更新,不会全量渲染
四、满分总结#
场景:#
跨层级共享全局状态(主题、语言、用户信息),解决 props 逐层传递。
性能风险:#
context 的 value 变化会导致所有使用它的组件全部重渲染,造成大面积无效渲染。
优化:#
拆分 Context、缓存 value、组件拆分、使用专业状态库。
总结#
- 适用:全局/跨层共享数据
- 风险:value 变 → 所有消费者全量重渲染
- 优化:拆分 + 缓存 + 专业状态库