React 轻量级状态管理器Zustand

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" }
  )
);

更多用法

相关推荐
foxhuli229几秒前
禁止ifrmare标签上的文件,实现自动下载功能,并且隐藏工具栏
前端
青皮桔32 分钟前
CSS实现百分比水柱图
前端·css
失落的多巴胺32 分钟前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear35 分钟前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息37 分钟前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月38 分钟前
1.vue权衡的艺术
前端·vue.js·开源
样子201842 分钟前
Vue3 之dialog弹框简单制作
前端·javascript·vue.js·前端框架·ecmascript
kevin_水滴石穿43 分钟前
Vue 中报错 TypeError: crypto$2.getRandomValues is not a function
前端·javascript·vue.js
翻滚吧键盘44 分钟前
vue文本插值
javascript·vue.js·ecmascript
666HZ6661 小时前
微信小程序中scss、ts、wxml
微信小程序·小程序·scss