
内容目录
Toggle序言
为什么要分享这项技术?
与 Redux 相比,Zustatnd 本身是一种相对较新的技术,它也是我的团队正在尝试实施的一种前端状态管理技术。通过实际实施,我有了一些经验和想法,然后就有了写这篇文章的想法。
现有架构遇到了什么问题?
无论是使用 Redux 还是 Context 来处理状态管理,Zustand 都比 Zustand 复杂,对于后来加入项目的工程师来说,需要花时间去理解它。Zustand 的主要目标是让前端状态管理变得相对简单易懂,这一特性让 Zustand 成为一些公司的选择。
关于状态管理
在介绍 Zustand 之前,先来了解一下什么是 "状态管理"?
目前,网页变得越来越复杂,前端和后端之间也有区别,其中前端更偏向于屏幕呈现、UI (用户体验)、用户流、不同设备的运行版本......等等。
后端更多的是功能实现,包括数据库管理、登录、注册......等等。
后来针对前端越来越复杂的情况,也开始有了框架的概念,目前流行的三大框架分别是 React、Vue、Angular。
例如,不同的框架也会有不同的 "状态管理 "方式:
React:基本上,你只需管理数据,并根据 "状态 "进行渲染。
Vue:"数据与组件的 "双向绑定
根据 React 框架,可大致分为以下几类
Local State
-
- useState
-
- useReducer
Context
-
- useContext
第三方
-
- Redux
-
- Mobx
-
- Zustand
由此可见,React 框架中的 "状态管理 "已经相当复杂。
因此,本文只着重介绍 Zustand,并将使用实际例子来介绍它。
我们还可以通过比较以下软件包的总下载量,了解 Redux、Mobx 和 Zustand 在过去一年中的受欢迎程度。

什么是 Zustand?
根据 Zustand 的说法,这是一个轻量级、快速的 "状态管理 "套件,基于 Flux 和 Hook 概念。
附注:上面的熊是 Zustand 的标志性吉祥物!
Zustand 还设计用于解决复杂的 React 状态管理问题,如僵尸子问题、React 并发、上下文丢失等。
如果您想进一步了解这些问题,可以参考以下链接
Zombie Child Problem:React Redux 文档
React Concurrency:官方 React 文档
React Context Loss:Stack Overflow
我们还可以通过 Zustand 的官方网站了解他们击败 Redux 的雄心壮志。
Zustand 使用
以下两种简单用法适用于 JavaScript 用户
创建第一个 Store
Zustand 基于 Hook 构建,因此创建的第一个存储空间是由自定义钩子创建的存储空间,它可以包含变量、对象和函数等。第一个创建的存储空间是自定义钩子创建的存储空间,它可以包含变量、对象和函数等。您还可以通过 Set 和 Get 对数据进行 "状态管理"。
import create from 'zustand' const useBearStore = create((set) => ({ bears: 0, increasePopulation: () => set((state) => ({ bears: state.bears + 1 })), removeAllBears: () => set({ bears: 0 }), }))
由于它使用钩子,因此可以直接加载到任何组件中使用。
这些状态也可以呈现,这对 Zustand 来说是一大福音,因为您可以看到只需几行字就可以完成。
下面是一个简单的 Zustand 示例,供 TypeScript 用户参考。
function BearCounter() { const bears = useBearStore((state) => state.bears) return {bears} around here ...
} function Controls() { const increasePopulation = useBearStore((state) => state.increasePopulation) return
}
Zustand TypeScript 写法
在 Zustand 中,我们将使用创建来创建一个新商店。
输入函数,通过钩子传回状态,然后重新渲染。
import create from "zustand" type Product = { sku: string; name: string; image: string } type CartState = { products: Product[] cart: { [sku: string]: number } addToCart: (sku: string) = > void removeFromCart: (sku: string) => void } // Selectors // ... // Initialize our store with initial values and actions to mutate the state export const useCart = create<CartState>(set => ({ products : [ // ... ], cart: {}, // Actions // ... }))
在此,我们还展示了 Redux 和 Mobx 的编写方式,以便读者比较两者的不同之处,但本文将不关注 Redux 或 Mobx,只关注 Zustand 及其状态管理。
Redux TypeScript 写法
import { createSlice, configureStore, PayloadAction } from "@reduxjs/toolkit" import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux" // Slices // Definee the shape of the state and how to mutate it type ICart = { [ sku: string]: number } const cartInitialState: ICart = {} const cartSlice = createSlice({ name: "cart", initialState: cartInitialState, reducers: { // ... }, }) type IProduct = { sku: string; name: string; image: string } const productsInitialState: IProduct[] = [ // ... ] const productsSlice = createSlice({ name: "products", initialState: productsInitialState, reducers: {}, }) // Actions // ... // Selectors // ... // Store export const store = configureStore({ reducer: { cart: cartSlice.reducer, products: productsSlice.reducer, }, }) // ... const App = () => { return ( <Provider store={store}> <NavigationContainer> <Stack.Navigator>{/* ... */}</Stack.Navigator> <StatusBar style="auto" /> </NavigationContainer> < /Provider> ) }
Mobx TypeScript 写法
import { types, Instance } from "mobx-state-tree" const Product = types.model({ sku: types.string, name: types.string, image: types.string, }) // Model and type our data with mobx state tree const CartStore = types .model("CartStore", { products: types.array(Product), cart: types.map(types.number), }) // Actions to mutate the state .actions(store => ({ // ... })) // Views are like selectors .views(self => ({ // ... })) type CartStoreType = Instance<typeof CartStore> // Spin up a hook to use our store and provide initial values to it let _cartStore: CartStoreType export const useCart = () => { if (!_cartStore) { _cartStore = CartStore.create({ products: [ // ... ], cart: {}, }) } return _cartStore }

根据 Zustand 官方的说法,在此列出并简要说明上述要点。
Redux
Redux 本身是一个更复杂的状态管理工具,会有 Actioins、View 和 State 流程。
以下是 Redux 官方数据流示意图,可以看出,如果想从头开始使用 Redux 的状态管理工具,学习门槛相对较高。

Redux Data Flow and React Component Life Cycle
几乎所有想学习 Redux 的人都见过这张图片。对我来说,这很简单,但...dev.to
Context
上下文本身被归类为状态管理,但实际上它更像是一种集中触发状态的方式。
与 Zustand 相比,它不容易管理,因为它分散在不同的文件中。

结论
使用该技术的优势
有了 Zustand,您就可以分解复杂业务逻辑的数据和逻辑,并对其进行建模。除了提高可读性,它还能让编写测试变得更容易。
使用心得
Zustand 本身就是一个充满易学性的状态管理工具,自己在工作产品中使用也比较方便,包括对状态进行 Set、Get 或者在组件中使用都比较方便,完全推荐给想要针对 React 进行状态管理的读者。
感谢您的收看 ~ 如果您有任何疑问或想讨论上述任何问题,请随时留言或给我发私人信息!
引用
https://github.com/pmndrs/zustand
https://react-redux.js.org/api/hooks#stale-props-and-zombie-children
https://docs.pmnd.rs/zustand/getting-started/comparison