zustand 是一个轻量级的状态管理器,它使用 React 的 hook 来实现状态管理。zustand 的 API 非常简单,只需要一个函数就可以创建一个状态管理器,并且可以非常方便地使用 React 的 hook 来访问和修改状态。
1. 安装
首先,我们需要安装 zustand 库。可以使用 npm 或者 yarn 来安装:
npm install zustand
or
yarn add zustand
2. 基本使用
2.1 创建 Store
import { create } from "zustand";
export const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
2.2 使用 Store
import React from "react";
import { useCounterStore } from "@/store/useCounterStore";
const Counter = () => {
const { count, increment, decrement } = useCounterStore();
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter;
3 示例
3.1 状态选择器
状态选择器允许你从 Zustand store 中选择特定的状态片段,而不是整个状态对象。这对于大型应用来说非常有用,因为它可以减少不必要的重新渲染,并提高性能。
const count = useCounterStore((state) => state.count);
3.2 异步操作
import { create } from "zustand";
export const useAsyncStore = create((set) => ({
data: null,
loading: false,
error: null,
fetchData: async (url) => {
set({ loading: true });
try {
const response = await fetch(url);
const data = await response.json();
set({ data, loading: false });
} catch (error) {
set({ error, loading: false });
}
},
}));
3.3 与 immer 使用,不可变数据
Zustand 的 Immer 中间件 是一个用于处理不可变状态更新的工具,它允许开发者以可变的方式编写代码,同时保证底层实现的不可变性。
import { create } from "zustand";
import { produce } from "immer";
export const useComplexStore = create((set) => ({
users: [],
addUser: (user) =>
set((state) =>
produce(state, (draft) => {
draft.users.push(user);
})
),
removeUser: (userId) =>
set((state) =>
produce(state, (draft) => {
draft.users = draft.users.filter((user) => user.id !== userId);
})
),
}));
3.4 持久化存储
Zustand Persist 是一个用于将状态持久化到存储中的中间件,支持将应用的状态保存到浏览器的存储中,例如 localStorage、sessionStorage、AsyncStorage 或 IndexedDB。这样,即使用户刷新页面或关闭浏览器,状态也不会丢失 。
import { create } from "zustand";
import { persist } from "zustand/middleware";
export const usePersistentStore = create(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}),
{
name: "persistent-storage",
}
)
);
3.5 devtools 中间件
Zustand DevTools 是一个工具,允许你将 Zustand 状态管理与 Redux DevTools 进行集成,从而更方便地调试应用状态。要在 Zustand 中集成 DevTools 进行状态调试。
import { create } from "zustand";
import { devtools } from "zustand/middleware";
export const useDevtoolsStore = create(
devtools(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}),
{ name: "devtools-store" }
)
);
3.6 Combine 中间件
3.6.1 状态和操作分离
import { create } from "zustand";
import { combine } from "zustand/middleware";
export const useSettingsStore = create(
combine(
{
theme: "light",
language: "zh",
notifications: true,
fontSize: "medium",
},
(set) => ({
setTheme: (theme) => set({ theme }),
setLanguage: (language) => set({ language }),
toggleNotifications: () =>
set((state) => ({ notifications: !state.notifications })),
setFontSize: (size) => set({ fontSize: size }),
})
)
);
3.6.2 状态组合和模块化
import { create } from "zustand";
import { combine } from "zustand/middleware";
// 用户模块
const userSlice = {
state: {
user: null,
isAuthenticated: false,
},
actions: (set) => ({
login: (user) => set({ user, isAuthenticated: true }),
logout: () => set({ user: null, isAuthenticated: false }),
}),
};
// 设置模块
const settingsSlice = {
state: {
theme: "light",
language: "zh",
},
actions: (set) => ({
setTheme: (theme) => set({ theme }),
setLanguage: (language) => set({ language }),
}),
};
// 组合多个模块
const useStore = create(
combine(
{
...userSlice.state,
...settingsSlice.state,
},
(set) => ({
...userSlice.actions(set),
...settingsSlice.actions(set),
})
)
);
3.7 shallow 性能优化
Zustand Shallow 是一个中间件,允许你使用浅比较来比较状态对象,而不是使用深度比较。这对于大型应用来说非常有用,因为它可以减少不必要的重新渲染,并提高性能。
import { create } from "zustand";
import { shallow } from "zustand/middleware";
export const useShallowStore = create(
shallow(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}),
{ name: "shallow-store" }
)
);
原文链接:https://code.ifrontend.net/archives/320,转载请注明出处。
评论0