跳到主要内容

切片模式

将 store 划分为更小的 store

随着我们添加更多功能,我们的 store 可能会变得越来越大,也越来越难以维护。

我们可以将主 store 划分为更小的单独 store,以实现模块化。在 Zustand 中,这很容易 实现!

第一个单独的 store:

import { StateCreator } from 'zustand';
import { FishSlice } from './use-fish-slice';

export interface BearSlice {
bears: number;
addBear: () => void;
eatFish: () => void;
}

export const createBearSlice: StateCreator<
BearSlice & FishSlice,
[],
[],
BearSlice
> = (set) => {
return {
bears: 0,
addBear: () => set((state) => ({ ...state, bears: state.bears + 1 })),
eatFish: () => set((state) => ({ ...state, fishes: state.fishes - 1 })),
};
};

另一个单独的 store :

import { StateCreator } from 'zustand';
import { BearSlice } from './use-bear-slice';

export interface FishSlice {
fishes: number;
addFish: () => void;
}

export const createFishSlice: StateCreator<
BearSlice & FishSlice,
[],
[],
FishSlice
> = (set) => ({
fishes: 0,
addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
});

我们现在可以将这两个 store 合并为一个 bounded store

import { create } from 'zustand';
import { BearSlice, createBearSlice } from './create-bear-slice';
import { FishSlice, createFishSlice } from './create-fish-slice';
import { persist } from 'zustand/middleware';

const useBoundStore = create<BearSlice & FishSlice & SharedSlice>()(
persist(
(...a) => ({
...createBearSlice(...a),
...createFishSlice(...a),
}),
{ name: '' }
)
);

export default useBoundStore;

在 React 组件中使用

import useBoundStore from './bound-store';

export default function StoreSliceDemo() {
const bears = useBoundStore((state) => state.bears);
const fishes = useBoundStore((state) => state.fishes);
const addBear = useBoundStore((state) => state.addBear);
const eatFish = useBoundStore((state) => state.eatFish);
return (
<div>
<h2>Number of bears: {bears}</h2>
<h2>Number of fishes: {fishes}</h2>
<button onClick={() => addBear()}>Add a bear</button>
<button onClick={() => eatFish()}>Eat a fish</button>
</div>
);
}

更新多 store

在同一个方法,同一时刻,我们可以更新多个 store。

共享 store:

import { StateCreator } from 'zustand';
import { BearSlice } from './create-bear-slice';
import { FishSlice } from './create-fish-slice';

export interface SharedSlice {
addBoth: () => void;
getBoth: () => number;
}

export const createSharedSlice: StateCreator<
BearSlice & FishSlice,
[],
[],
SharedSlice
> = (_set, get) => {
return {
addBoth: () => {
get().addBear();
get().addFish();
},
getBoth: () => {
return get().bears + get().fishes;
},
};
};

更新 bound store,增加共享 store:

import { create } from 'zustand';
import { BearSlice, createBearSlice } from './create-bear-slice';
import { FishSlice, createFishSlice } from './create-fish-slice';
import { createSharedSlice, SharedSlice } from './create-shared-slice';

const useBoundStore = create<BearSlice & FishSlice & SharedSlice>()((...a) => ({
...createBearSlice(...a),
...createFishSlice(...a),
...createSharedSlice(...a),
}));

export default useBoundStore;

添加中间件

向合并后的 store 添加中间件的方式与其他普通 store 相同。

添加 persist 中间件到我们的 useBoundStore 方法中:

import { create } from 'zustand';
import { BearSlice, createBearSlice } from './create-bear-slice';
import { FishSlice, createFishSlice } from './create-fish-slice';
import { createSharedSlice, SharedSlice } from './create-shared-slice';
import { persist } from 'zustand/middleware';

const useBoundStore = create<BearSlice & FishSlice & SharedSlice>()(
persist(
(...a) => ({
...createBearSlice(...a),
...createFishSlice(...a),
...createSharedSlice(...a),
}),
{ name: '' }
)
);

export default useBoundStore;

请注意,我们应该只在合并后的 store 中应用中间件。在单独的切片内部应用它们可能会 导致意外的问题。

使用 TypeScript

关于如何在 Zustand 中使用 TypeScript 的切片模式的详细指南可以在这里找到 :这里