Redux
Redux 是一个使用叫作 "actions" 的事件去管理和更新应用状态的模式和工具库,用于集中管理状态。 它以集中式 Store(centralized store)的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
"store" 是保存应用程序的全局 state 的容器,所有 Redux 应用的中心都是 store 。
- 通过 store.getState() 访问当前 state;
- 通过 store.dispatch(action) 更新状态;
- 通过 store.subscribe(listener) 注册监听器回调;
- 通过 store.subscribe(listener) 返回的 unsubscribe 函数注销监听器。
action 是一个有 type 字段的对象。描述应用程序中发生了什么的事件.
reducer 是一个函数,接收当前的 state 和一个 action 对象,必要时决定如何更新状态,并返回新状态
更新 state 的唯一方法是调用 store.dispatch() 并传入一个 action 对象
Selector 函数从 store 状态树中提取指定的片段,避免重复读取
js
const store = Redux.createStore((state,action) => newState)//state,reducer;
// const store = createStore(rootReducer,preloadState?) //创建根reducer
store.subscribe(()=> {console.log(store.getstate())}) //订阅,在每次更新store时调用回调函数
store.dispatch({ type : actiontype 」) // 创建action对象,dispath到store,运行reducer
createstore的实现
https://cn.redux.js.org/tutorials/fundamentals/part-4-store#:~:text=function%20createStore
在react-redux中,selector、dispatch、subscribe以hook方式使用; 通过<Provider store={store}> 包裹组件让该组件及其子组件共享store
const selectedStates = useSelector((state) => state.selectedKey)
//useSelector 会自动订阅 Redux store,不用担心通过其获得的状态不是最新值
const dispatch = useDispatch() // useDispatch的实现就是 return store.dispatch
if(some action){dispatch({type:actionType})}
Zustand
- Introduction -- job, usage , ...
Don't disregard it because it's cute, it has claws
Zustand 同样用于管理全局状态,但更加轻量、易用。
使用方法:
js
//1. 创建storeHook
import { create } from 'zustand'
const useStore = create((set,get) => ({
//两个参数 set 和 get,分别用于更新和获取状态。
statename: initialValue,
someFunction: () => set((state) => ({ statename: newValue}))
}))
//2. 通过钩子获取状态
const { statename,someFunction } = useStore(); //
//使用selecror
const {statename,...} = useStore((state) => state.statename)
zustand的state更新都需要触发set函数,更新新状态默认方式是与现有状态进行浅合并
要注意的是,selector会subscrbe对应的状态,状态变化(默认采用===)重新渲染引入其的组件,可以提供自定义的对比函数
const treats = useBearStore(
(state) => state.treats,
(oldTreats, newTreats) => compare(oldTreats, newTreats)
)
Middleware
redux 和 zustand 都支持中间件(middleware),用于在状态更新的过程中执行额外的逻辑。
1. Redux MiddleWare
在 redux 中,中间件在 dispatch 到一个 action 和 reducer 处理这个 action 的中间执行
js
//Redux MiddleWare原型
type Middleware = (store: MiddlewareAPI) =>
(next: Dispatch) =>
(action: AnyAction) => any;
const store = createStore(reducer, applyMiddleware(logger));
const loggerMiddleWare = store => next => action => {
console.log('dispatching', action);
let result = next(action); //next将 action 传递给下一个中间件或 reducer
console.log('next state', store.getState()); //reducer处理后的状态
return result;
};
2. Zustand MiddleWare
zustand 中,中间件用于包装状态创建函数,给set添加额外逻辑
js
type Middleware<TState> = config => (set,get,api) => config
const logMiddleWare_zustand = (config) => (set, get, api) =>
config(
(...args) => {
console.log('applying', args);
set(...args);//set
console.log('new state', get());
},
get,
api
);
const useBeeStore = create(
log((set) => ({
bees: false,
setBees: (input) => set({ bees: input }),
}))
)
Redux和Zustand区别
- 状态存储
Zustand使用hooks创建和管理状态,可以有多个独立的状态存储
Redux使用单一状态树(单一的store),需要通过Provider包裹将store注入到组件中。 - 状态更新
zustand在组件中直接通过hooks引入状态,直接进行更新
Redux通过dispatch+action更新状态
两者状态更新默认都是浅合并 - 异步处理
zustand可以在创建函数中直接处理异步操作
js
const useStore = create((set) => ({
data: null,
fetchData: async () => {
const data = await fetch('/api/data');
set({ data });
},
}));
Redux store 本身无法处理异步逻辑。它只会同步地 dispatch action,并通过调用根 reducer 函数来更新 state,然后通知视图更新。任何异步都必须在 store 之外发生。
常通过中间件处理
const fetchData = () => async (dispatch) => {
const data = await fetch('/api/data');
// 使用获取到的 数据来 dispatch 一个 action
dispatch({ type: 'SET_DATA', payload: data });
};