状态管理是 React 开发中永恒的话题。从 Context API 到 Redux,再到新兴的 Zustand 和 Jotai,选择之多让很多开发者感到困惑。本文将对比四种主流方案,帮你做出最适合项目的技术选型。
Context API:React 内置方案
// 1. 创建 Context\nconst ThemeContext = createContext('light');\n\n// 2. Provider 提供值\nfunction App() {\n const [theme, setTheme] = useState('light');\n return (\n <ThemeContext.Provider value={{ theme, setTheme }}>\n <Child />\n </ThemeContext.Provider>\n );\n}\n\n// 3. Consumer 消费值\nfunction Child() {\n const { theme, setTheme } = useContext(ThemeContext);\n return <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>\n {theme}\n </button>;\n}优点:零依赖、API 简洁、适合中低频更新的全局状态。
缺点:Context 值变化时,所有消费该 Context 的组件都会重渲染(没有 selector 机制);不适合高频更新的状态(如输入框值、动画状态);多个 Context 嵌套会导致 Provider Hell。
Redux Toolkit:企业级方案
// store.ts\nimport { configureStore, createSlice } from '@reduxjs/toolkit';\n\nconst userSlice = createSlice({\n name: 'user',\n initialState: { name: '', loggedIn: false },\n reducers: {\n login(state, action) { state.name = action.payload; state.loggedIn = true; },\n logout(state) { state.name = ''; state.loggedIn = false; },\n },\n});\n\nexport const { login, logout } = userSlice.actions;\nexport const store = configureStore({ reducer: { user: userSlice.reducer } });// Component.tsx\nfunction UserProfile() {\n const user = useSelector((state: RootState) => state.user);\n const dispatch = useDispatch();\n return (\n <div>\n <span>{user.name}</span>\n <button onClick={() => dispatch(logout())}>退出</button>\n </div>\n );\n}优点:完善的 DevTools(时间旅行调试)、中间件生态丰富、社区最大、适合大型团队协作。
缺点:样板代码较多(即使使用 RTK),学习曲线较陡,对小项目来说过于重型。
Zustand:轻量级状态管理的新星
import { create } from 'zustand';\n\nconst useUserStore = create((set) => ({\n user: null,\n loading: false,\n login: async (name) => {\n set({ loading: true });\n await fetchUser(name);\n set({ user: name, loading: false });\n },\n logout: () => set({ user: null }),\n}));\n\n// 使用(支持 selector 避免不必要的重渲染)\nfunction UserProfile() {\n const user = useUserStore((state) => state.user);\n const login = useUserStore((state) => state.login);\n return <div>{user?.name}</div>;\n}优点:API 极简(核心不到 1KB)、无需 Provider 包裹、天然支持在组件外部读写状态、对 TypeScript 友好、性能优秀(基于 selector 的细粒度订阅)。
缺点:生态不如 Redux 成熟,缺少内置的中间件机制。
Pinia:Vue 生态的启示
虽然是 Vue 的状态管理库,但 Pinia 的设计思想值得 React 生态借鉴:模块化的 Store 定义、完整的 TypeScript 支持、DevTools 集成。Zustand 在很多方面借鉴了 Pinia 的设计。
方案对比总结
| 方案 | 包大小 | 学习曲线 | 性能 | 生态 | 推荐场景 |
|---|---|---|---|---|---|
| Context API | 0KB | 低 | 无 selector,注意重渲染 | 内置 | 主题、语言等低频全局状态 |
| Redux Toolkit | ~11KB | 中高 | 优秀(selector + immer) | 最大 | 大型企业级应用 |
| Zustand | ~1KB | 低 | 优秀(selector) | 快速增长 | 中小型应用(推荐首选) |
| Jotai | ~2KB | 低 | 优秀(原子化) | 中等 | 细粒度组件状态 |
选型建议
中小型项目(推荐):Zustand——简单、性能好、无需 Provider。大型企业级应用:Redux Toolkit + RTK Query——完善的生态、强大的 DevTools。只需少量全局状态:Context API——零依赖,够用就好。需要原子化状态管理:Jotai——比 Recoil 更轻量、更活跃。
总结
状态管理没有银弹,最好的工具是你和团队用起来最顺手的工具。但一个通用原则是:从最简单的方案开始,遇到瓶颈再升级。不要因为项目"可能"会变得复杂,就在第一天引入 Redux。
评论 (0)