Page cover

zustand

zustand 是一个使用简化的 flux 原理的小型、快速和可扩展的 bearbones 状态管理解决方案。基于hooks 有一个的 API。

简单使用

你的 store 是一个 hook!你可以在里面放任何内容:基本类型、对象、函数。状态必须不可变地更新,并且 set 函数合并状态arrow-up-right来帮助它。

import { create } from "zustand";

const useCount = create((set) => ({
    count: 0,
    plus: () => set((state) => ({count: state.count + 1})),
    minus: () => set((state) => ({count: state.count - 1})),
    reset: () => set({count: 0}),
}));

然后绑定你的组件,在任何地方使用 hook,不需要 provider。选择你的状态,组件将在 state 更改时重新渲染。

function Counter() {
    const count = useCount((state) => state.count);
    return <h1>{count}</h1>;
}

function Controls() {
    const plus = useCount((state) => state.plus);
    const minus = useCount((state) => state.minus);
    const reset = useCount((state) => state.reset);

    return (
        <>
            <button onClick={plus}>+</button>
            <button onClick={minus}>-</button>
            <button onClick={reset}>重置</button>
        </>
    );
}
triangle-exclamation

state 更新渲染组件

切片状态(slice state),因为 store 是一个原子状态,它可以切分为多个格子状态,便于代码管理。

单个 state 更新渲染

默认情况下,它以严格相等(old === new)检测更改,这对于原子状态选择非常有效。

多个 state 更新渲染

如果想要构造一个内部有多个 state-pick 的单个对象,类似于 redux 的 mapStateToProps,你可以使用 useShallowarrow-up-right 来防止当 selector 输出没有根据 shallow 相等而改变时不必要的重新渲染。

自定义函数控制渲染

为了更好地控制渲染,可以提供任何自定的函数。

覆盖 state

set 函数有第二个参数,默认为 false,它将取代 state 模型,而不是合并。注意它会抹去你依赖的部分,比如 actions。

异步操作

从 action 中读取 state

记忆处理器

useCallback

通常建议使用 useCallback 记忆处理器。 这将防止每次渲染时进行不必要的计算。 它还允许 React 在并发模式下优化性能。

不依赖于作用域的处理器

如果一个处理器不依赖于作用域,可以在渲染函数之外定义它以获得一个固定的“引用”而无需 useCallback。

在 React 组件之外读写 state

自定义 hooks 读写 state

使用订阅处理器(中间件)

如果您需要使用处理器订阅,subscribeWithSelector 中间件会有所帮助。

有了这个中间件,subscribe 接受一个额外的签名:

订阅处理器(中间件)使用 TS

瞬时更新 ref(用于频繁发生的状态变化)

订阅功能允许组件绑定到 state,而无需在更改时强制重新渲染。 最好将它与 useEffect 结合使用,以便在卸载时自动取消订阅。 当直接改变视图时,这会对性能产生巨大影响。

更新嵌套的状态,使用

Immer

中间件

按自己喜欢的方式管理 store

管理中间件

在管理中间件中使用 TS

状态持久化中间件 persist

像 Redux 一样编写代码

或者,使用 redux-middleware

在 React 事件处理程序之外调用 actions

如果在 React 事件处理程序之外调用setState,它会同步处理。 在事件处理程序之外更新状态将强制 react 同步更新组件,因此增加了遇到僵尸子效应的风险。 为了解决这个问题,需要将 actions 包裹在unstable_batchedUpdates中。

使用 Redux 开发工具

Name store: devtools(store, {name: "MyStore"}),这将在 devtools 中创建一个名为“MyStore”的单独实例。 序列化选项:devtools(store, { serialize: { options: true } })

React context

store create 不需要上下文提供程序(context providers)。 在某些情况下,你可能希望使用上下文进行依赖注入,或者如果你想使用组件中的 props 初始化 store。 因为 store 是一个钩子,把它作为一个普通的上下文值传递可能会违反钩子的规则。 为了避免误用,提供了一个特殊createContext

在组件中使用

3. createContext 使用 props 初始化(在 TS 中)

TypeScript 类型定义

1. 类型定义

2.使用combine 并让 tsc 推断类型

最后更新于