背景
最近公司有个h5的需求,h5相对简单,移动端嘛,讲究的是轻巧。
之前pc端用的状态管理是Redux Toolkit 确实很强大好用,但是对于h5来说体积太大了。
看下npm上的包体积对比


基本的使用
创建 store/index.ts
import create from "zustand";
type HandleType = "add" | "jianshao";
interface InitialState {
count: number;
userInfo: { name?: String; age?: number };
changeCount: (type: HandleType) => void;
fetchData: (type?: any) => void;
}
const useGLobalStore = create<InitialState>((set, get) => ({
count: 0,
userInfo: {},
changeCount: (type) => {
if (type === "add") {
set({ count: get().count + 1 });
} else {
set((state) => ({ count: state.count - 1 }));
}
},
fetchData: async (params?: any) => {
const res: any = await requestData(params);
set({ userInfo: res.data.userInfo });
},
}));
export { useGLobalStore };
function requestData(params?: any) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
userInfo: {
name: "jianjian",
age: 12,
},
},
});
}, 2000);
});
}
使用
import { useGLobalStore } from "./store";
import shallow from "zustand/shallow";
const App = () => {
const { count, userInfo, changeCount, fetchData } = useGLobalStore(
(state) => ({
count: state.count,
userInfo: state.userInfo,
changeCount: state.changeCount,
fetchData: state.fetchData,
})
);
return (
<div>
<span>count: {count}</span>
<span>name: {userInfo.name}</span>
<span>age: {userInfo.age}</span>
<button onClick={() => changeCount("add")}>增加</button>
<button onClick={() => changeCount("jianshao")}>减少</button>
<button onClick={() => fetchData()}>请求数据</button>
</div>
);
};
export default App;
结合中间件的使用
修改store/index.ts
import create from "zustand";
++import { devtools, persist } from "zustand/middleware";
type HandleType = "add" | "jianshao";
interface InitialState {
count: number;
userInfo: { name?: String; age?: number };
changeCount: (type: HandleType) => void;
fetchData: (type: any) => void;
}
++为啥create<InitialState>()这里要加括号 可[查看](https://github.com/pmndrs/zustand/blob/main/docs/guides/typescript.md)
++const useGLobalStore = create<InitialState>()(
++persist(
++ devtools((set, get, api) => ({
++ count: 0,
++ userInfo: {},
++ changeCount: (type) => {
++ if (type === "add") {
++ // 对象写法通过get可以获取到store中的数据
++ set({ count: get().count + 1 });
++ } else {
++ // 也可以通过函数写法获取到store中的数据
++ set((state) => ({ count: state.count - 1 }), false, "global/change");
++ }
++ },
++ fetchData: async (params: any) => {
++ const res: any = await requestData(params);
++ set((state) => ({ userInfo: res.data.userInfo }), false);
++ // set((state) => ({ userInfo: res.data.userInfo }), true);
++ // set({ userInfo: res.data.userInfo });
++ },
++ })),
++ { name: "jianjian" }
++ )
++);
export { useGLobalStore };
function requestData(params: any) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
userInfo: {
name: "jianjian",
age: 12,
},
},
});
}, 2000);
});
}
1 我们引入了中间价devtools(可以调用redux的浏览器工具)persist(可以讲zustand中的数据存储在localstorage中)
2 set((state) => ({ count: state.count - 1 }), false, "global/change");第二个参数默认为false, 修改数据会和之前的数据进行合并, 如何为true, 会把之前的数据替换,而不是合并(慎用)第三个参数global/change就是我们在redux调试工具中的type类型
3 上面例子中的 { name: "jianjian" } 是我们调用persist中间件存在localstorage中的key
如何实现模块化管理
新建文件 store/bearStore.ts
import type { StateCreator } from "zustand";
import { FishSlice } from "./fishStore";
export interface BearSlice {
bears: number;
addBear: () => void;
reduceBear: () => void;
}
export const createBearSlice: StateCreator<
BearSlice & FishSlice,
[["zustand/persist", unknown], ["zustand/devtools", never]],
[],
BearSlice
> = (set) => ({
bears: 0,
addBear: () => set((state) => ({ bears: state.bears + 1 })),
reduceBear: () => set((state) => ({ bears: state.bears - 1 })),
});
新建文件 store/fishStore.ts
import type { StateCreator } from "zustand";
import { BearSlice } from "./bearStore";
export interface FishSlice {
fishes: number;
addFish: () => void;
: () => void;
}
export const createFishSlice: StateCreator<
FishSlice & BearSlice,
[["zustand/persist", unknown], ["zustand/devtools", never]],
[],
FishSlice
> = (set) => ({
fishes: 0,
addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
eatFish1: () => set((state) => ({ fishes: state.fishes - 1 })),
});
修改store/index.ts
import create from "zustand";
import { devtools, persist } from "zustand/middleware";
import { FishSlice, createFishSlice } from "./fishStore";
import { BearSlice, createBearSlice } from "./bearStore";
const useGLobalStore = create<BearSlice & FishSlice>()(
persist(
devtools((...a) => {
return {
...createBearSlice(...a),
...createFishSlice(...a),
};
})
)
);
export { useGLobalStore };