❓你是否觉得 Redux 写起来像“国家级项目”?
❓你是否在组件之间疯狂传 props?
❓你是否曾羡慕过 Vuex 的简洁?
今天这篇文章,将带你掌握 React 中 “无需 Redux 也能全局管理状态”的几种优雅方式,让你从状态地狱中解放出来。
✨ 前言:全局状态管理的“痛点”从哪来?
React 本身只专注于视图层渲染,它并没有提供内置的全局状态解决方案(不像 Vue 内置了 reactive + provide/inject + Pinia)。
但当我们的项目越来越大,就不可避免需要“跨组件共享数据”,于是我们面对的问题有:
- ❌ 父传子、子传孙,props 层层嵌套
- ❌ Redux 配置复杂、样板代码多
- ❌ Context 用多了逻辑混乱
🎯 本文目标
掌握 React 中最实用的全局状态管理方案:
工具 | 适用场景 | 特点 |
---|---|---|
React Context | 简单共享、轻量级全局状态 | 原生,官方支持 |
Zustand | 轻量、组合式、无模板代码 | 类似 Vue 的 Pinia |
Jotai | 原子化状态管理 | 响应式更新更细颗粒度 |
Redux Toolkit | 大型复杂项目 | 模板化 + 工程体系健全 |
🧩 一、React Context:原生方案,轻量上手
如果只是想让某些状态“跨组件共享”,可以用 React Context + useReducer
,类似 Vue 的 provide/inject
+ store
。
🎬 示例:用户登录状态管理
// context/user.tsx
import { createContext, useReducer, useContext } from "react";
const UserContext = createContext();
function reducer(state, action) {
switch (action.type) {
case "LOGIN":
return { ...state, user: action.payload };
case "LOGOUT":
return { ...state, user: null };
default:
return state;
}
}
export function UserProvider({ children }) {
const [state, dispatch] = useReducer(reducer, { user: null });
return (
<UserContext.Provider value={{ state, dispatch }}>
{children}
</UserContext.Provider>
);
}
export const useUser = () => useContext(UserContext);
在组件中使用:
const { state, dispatch } = useUser();
dispatch({ type: "LOGIN", payload: { name: "主人" } });
📌 优点:
- 无需额外依赖
- 轻量、明确
⚠️ 缺点:
- 无法响应式拆分(Context 更新会触发所有订阅者)
- 写多了容易变复杂
🧬 二、Zustand:组合式状态管理,轻松写出 Vue Pinia 的味道
★
✅ 轻量 ✅ 零样板 ✅ 支持持久化 ✅ TypeScript 支持完美
”
npm install zustand
🎬 示例:创建状态仓库
// store/useCounter.ts
import { create } from 'zustand';
export const useCounter = create((set) => ({
count: 0,
inc: () => set((state) => ({ count: state.count + 1 })),
}));
使用:
const { count, inc } = useCounter();
return <button onClick={inc}>点击了 {count} 次</button>;
📌 优点:
- 简洁、组合式写法
- 支持局部更新
- 支持 devtools、persist、immer 等插件
👀 看起来是不是很像 Vue 的 defineStore
?
🧪 三、Jotai:原子状态,极致响应式
npm install jotai
适合对“响应式更新粒度”要求极高的场景。每个状态就是一个原子(atom),用多少、更新多少。
🎬 示例:
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
📌 优点:
- 响应式原子,更新粒度最细
- 状态组合优雅
⚠️ 缺点:
- 学习成本稍高,不适合太多协作者的项目
🏢 四、Redux Toolkit:企业级别的状态管理框架
如果你来自 Vue + Vuex 的背景,Redux 初体验可能很反感。
但是现在的 Redux Toolkit 解决了大部分痛点:
- ✂️ 精简模板代码
- ✨ 内置 Immer,可直接写 “可变” 状态
- ⚙️ 自动生成 action + reducer
npm install @reduxjs/toolkit react-redux
示例(简化版)
// store.ts
import { configureStore, createSlice } from '@reduxjs/toolkit';
const counter = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
inc: (state) => { state.count += 1 },
}
});
export const store = configureStore({ reducer: { counter: counter.reducer } });
export const { inc } = counter.actions;
组件中使用:
const count = useSelector((state) => state.counter.count);
const dispatch = useDispatch();
<button onClick={() => dispatch(inc())}>{count}</button>
📌 适用:
- 大型应用,多人协作
- 多模块/中间件需求
📊 状态管理工具对比总结
特性/工具 | Context | Zustand | Jotai | Redux Toolkit |
---|---|---|---|---|
零依赖 | ✅ | ❌ | ❌ | ❌ |
简单易学 | ✅ | ✅✅ | ❌ | ❌ |
响应式粒度 | ❌ | ✅ | ✅✅ | ✅ |
插件生态 | ❌ | ✅✅ | ✅ | ✅✅✅ |
适合大型项目 | ❌ | ✅ | ❌ | ✅✅✅ |
📌 最佳实践推荐
项目类型 | 推荐方案 |
---|---|
小型项目 / Demo | React Context or Zustand |
中型项目 | Zustand (或 Jotai) |
大型项目 / 企业应用 | Redux Toolkit |
对响应性能要求高 | Jotai |
🧠 小结
React 虽然不像 Vue 那样内建状态系统,但它提供了灵活多样的生态和组合方式。根据项目规模、协作需求、响应粒度,选择最适合的全局状态方案,才是最优雅的实践!
本文使用 markdown.com.cn 排版