React Context 的原理和性能问题是什么?如何优化?
Context 基本用法
const ThemeContext = createContext('light')
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
)
}
function Child() {
const theme = useContext(ThemeContext)
return <div>{theme}</div> // 'dark'
}原理
- Provider 的 value 变化时,React 会重新渲染所有消费该 Context 的组件
- 即使子组件被
React.memo包裹,Context 变化也会跳过 memo 直接渲染
性能问题
问题:Provider value 每次渲染都是新对象,导致所有消费者重渲染
// ❌ 每次渲染都创建新对象
function App() {
const [count, setCount] = useState(0)
return (
<UserContext.Provider value={{ user, logout }}>
{/* count 变化时,即使用户信息没变,消费 UserContext 的组件也会重渲染 */}
<ExpensiveTree />
</UserContext.Provider>
)
}优化方案
1. useMemo 缓存 value
function App() {
const [count, setCount] = useState(0)
const [user, setUser] = useState(null)
const value = useMemo(() => ({ user, logout }), [user])
return (
<UserContext.Provider value={value}>
<ExpensiveTree />
</UserContext.Provider>
)
}2. 拆分 Context
// 将频繁变化的和不变的分开
const UserContext = createContext() // 不常变化
const ThemeContext = createContext() // 偶尔变化
const CartContext = createContext() // 频繁变化
// 各自独立 Provider
<UserContext.Provider value={userValue}>
<ThemeContext.Provider value={themeValue}>
<CartContext.Provider value={cartValue}>
<App />
</CartContext.Provider>
</ThemeContext.Provider>
</UserContext.Provider>3. use-context-selector(第三方库)
import { createContext, useContextSelector } from 'use-context-selector'
const UserContext = createContext()
function Name() {
// 只订阅 user.name,其他属性变化不触发
const name = useContextSelector(UserContext, state => state.name)
return <div>{name}</div>
}4. 状态下放
// ❌ count 在 Provider 外面,变化不影响 Provider
function App() {
return (
<UserContext.Provider value={value}>
<Counter /> {/* count 变化不影响其他消费者 */}
</UserContext.Provider>
)
}
const Counter = React.memo(() => {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
})什么时候用 Context
- ✅ 主题、用户信息、语言等低频变化的全局状态
- ✅ 依赖注入(如路由、Store)
- ❌ 频繁变化的状态(购物车、实时数据)→ 用 Zustand/Jotai
替代方案对比
| 方案 | 适合场景 | 性能 |
|---|---|---|
| Context | 低频全局状态 | 中(需优化) |
| Zustand | 通用全局状态 | 好 |
| Jotai | 细粒度原子状态 | 优秀 |
| Redux | 大型复杂应用 | 好 |