【React】Redux、Recoil、jotai、zustand 几个状态管理库的对比

Redux

核心概念:

单一数据源:所有的状态存储在一个全局的 store 中 状态是只读的: 只能通过派发 action 来修改状态 纯函数 Reducer: 状态的修改只能通过纯函数 reducer 处理,接收当前状态和 action,返回新状态

使用方式

1、创建 Store

javascript 复制代码
import { createStore } from 'redux';

const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};
const store = createStore(reducer);


store.subscribe(() => console.log(store.getState()))  
  
// 改变内部状态的唯一方法是 dispatch 一个 action。  
store.dispatch({ type: 'INCREMENT' })  

Redux-toolkit 的写法,消除 Redux 逻辑中的【样板代码】,看上去是简化了不少。 主要做的事情有

  • configureStore 通过函数调用设置一个配置完善的 Redux store, 包括合并 reducer,添加 thunk 中间件以及设置 Redux DevTool 集成。
javascript 复制代码
import { configureStore } from '@reduxjs/toolkit'
import todosReducer from '../features/todos/todosSlice'
import filtersReducer from '../features/filters/filtersSlice'

export const store = configureStore({
  reducer: {
    todos: todosReducer,
    filters: filtersReducer
  }
})
  • createSlice 使用 Immer 库来编写 reducer,可以使用 "mutating JS" 语法,比如 state.value = 123, 不需要使用扩展运算符。内部基于你的 reducer 名称生成 action type 字符串。 action createors 和 action type 都自动生成了
go 复制代码
// 最原始的写法
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};
css 复制代码
// 使用 redux-tookit
 reducers: {
    incremented: state => {
      state.value += 1
    }

完整的使用 redux-tookit的例子

ts 复制代码
import { createSlice, configureStore } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0
  },
  reducers: {
    incremented: state => {
      // Redux Toolkit 允许在 reducers 中编写 "mutating" 逻辑。
      // 它实际上并没有改变 state,因为使用的是 Immer 库,检测到"草稿 state"的变化并产生一个全新的
      // 基于这些更改的不可变的 state。
      state.value += 1
    },
    decremented: state => {
      state.value -= 1
    }
  }
})

export const { incremented, decremented } = counterSlice.actions

const store = configureStore({
  reducer: counterSlice.reducer
})

// 可以订阅 store
store.subscribe(() => console.log(store.getState()))

// 将我们所创建的 action 对象传递给 `dispatch`
store.dispatch(incremented())
// {value: 1}

总结是用 redux toolkit 的好处

  • Redux Toolkit 消除手写的 action creator 、action type的需求
  • Redux Toolkit 消除了容易出错的手动不可变更新逻辑的需求
  • Redux Toolkit 通过单一清晰的函数调用简化 store 设置,同时保留完全配置 store 选项的能力

Recoil

核心概念

  • Atom: 最小的状态单元,类似于 Redux 的 State
  • Selectors: 基于 atom 的派生状态,类似于计算属性
  • React 集成: 通过 Hook(如 useRecoilState)直接与 React 组件绑定
ts 复制代码
import { atom, selector, useRecoilState } from 'recoil';

const countState = atom({
  key: 'countState',
  default: 0,
});

const doubleCount = selector({
  key: 'doubleCount',
  get: ({ get }) => get(countState) * 2,
});

Jotai

核心概念: 类似 Recoil 的原子化状态管理,但是更加轻量,强调组合型和简洁 API

底层原理:

  • Atom: 通过 atom() 定义原子状态,原子之间可以组合(类似函数式编程)
  • Atoms: 类似于 Recoil 的原子状态,但是更加简洁
  • 无 Provider: 不需要 Redux 或 Recoil 那样包裹组件
ts 复制代码
import { atom, useAtom } from 'jotai';

const countAtom = atom(0);
const doubleCountAtom = atom((get) => get(countAtom) * 2);

在组件中使用

ts 复制代码
const App = () => {
  const [count, setCount] = useAtom(countAtom);
  const [doubled] = useAtom(doubleCountAtom);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Doubled: {doubled}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

Zustand

核心概念

  • 单一 Store: 类似 Redux
  • 函数更新:通过函数直接修改状态
  • 无 Action/Reducer:直接操作状态,减少复杂性

底层原理

  • Store: 状态存储在外部 JavaScript 对象中,通过 createStore 创建。
  • 发布-订阅模式: 组件通过useStore Hook 订阅状态变化,Store 内部维护一个订阅者列表,当状态变化时通知所有订阅者
  • 选择器(Selector): 支持传入选择器函数(如 useStore(state=>state.count)),通过钱比较避免重复渲染
  • Middleware 支持: 可以通过中间件扩展功能。
  • 脱离了 React Context:Zustand 不依赖 React Context 传递 Store,直接通过闭包和订阅机制管理状态,避免了 Context 层级问题
ts 复制代码
import { create } from 'zustand';

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  doubleCount: (state) => state.count * 2,
}));

在组件中使用

javascript 复制代码
const App = () => {
  const { count, increment, doubleCount } = useStore();
  const doubled = useStore(doubleCount);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Doubled: {doubled}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
};

对比总结

特性 Redux Recoil Jotai Zustand
状态模型 单一 Store 原子化状态 原子化状态 外部 Store
更新机制 Dispatch Action 直接更新 Atom 直接更新 Atom 直接修改 Store
性能优化 浅比较(需手动优化) 自动依赖追踪 自动依赖追踪 选择器 + 浅比较
异步支持 需中间件(如 Thunk) 内置异步 Selector 需手动处理 直接处理
与 React 集成 需 React-Redux 深度集成 深度集成 轻量集成
适用场景 大型复杂应用 细粒度状态管理 轻量原子化状态 简单全局状态
相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax