react全局状态管理——redux和zustand,及其区别

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

  1. 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区别

  1. 状态存储
    Zustand使用hooks创建和管理状态,可以有多个独立的状态存储
    Redux使用单一状态树(单一的store),需要通过Provider包裹将store注入到组件中。
  2. 状态更新
    zustand在组件中直接通过hooks引入状态,直接进行更新
    Redux通过dispatch+action更新状态
    两者状态更新默认都是浅合并
  3. 异步处理
    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 });
};
相关推荐
Nan_Shu_61415 分钟前
学习: Threejs (2)
前端·javascript·学习
G_G#23 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界39 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路1 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug1 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121381 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
冰暮流星1 小时前
javascript逻辑运算符
开发语言·javascript·ecmascript