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 | 深度集成 | 深度集成 | 轻量集成 |
适用场景 | 大型复杂应用 | 细粒度状态管理 | 轻量原子化状态 | 简单全局状态 |