本文最后更新于 2024-06-19,本文发布时间距今超过 90 天, 文章内容可能已经过时。最新内容请以官方内容为准

Zustand: 简化你的 React 状态管理 📦✨

Zustand 是一个轻量级且易于使用的状态管理库,它通过提供简洁的 API 来简化 React 应用中的状态共享。

以下是 Zustand 的一些核心概念和函数,以及如何使用它们。

🌐 Zustand 的核心 API

在 Zustand 状态管理库中,createcreateStore 都是用于创建 store 的函数,但它们的使用场景和返回的内容略有不同。

create

create是 Zustand 的基础 API,用于创建一个状态管理 store。它返回一个 React Hook,可以在函数组件中使用,以访问和修改状态。

createStore

createStore允许你创建一个不依赖于 React 的 store。这个 store 可以在任何 JavaScript 环境中使用,包括服务端渲染、测试或其他框架。

🔌 扩展 API

useStore

useStore是一个通用 Hook,用于订阅和访问由createStore创建的 store 的状态和方法。它提供了一种方式,使得在 React 组件之外也能访问 store。

subscribe

subscribe函数允许你监听 store 的状态变化。你可以提供一个回调函数,当 store 的状态更新时,这个回调函数将被执行。

getState

getState是一个方法,返回 store 的当前状态。这在需要直接访问 store 状态时非常有用,尤其是在非 React 环境中。

setState

setState是一个方法,用于更新 store 的状态。它接受一个函数,该函数接收当前状态作为参数,并返回新的状态。

🔰 Zustand 的 createcreateStore:区别与用法

在 Zustand 状态管理库中,createcreateStore 都是用于创建 store 的函数,但它们的使用场景和返回的内容略有不同。

使用 create 在 React 组件中管理状态

create 是 Zustand 库的基础 API,用于创建状态管理 store。它返回一个 React Hook,用于在组件中访问和操作 store 的状态,适用于大多数 React 项目中,特别是在函数组件中使用。

使用示例

import create from 'zustand';

type BearState = {
  bears: number;
  increase: () => void;
};

const useStore = create<BearState>((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
}));

export default function BearCounter() {
  const { bears, increase } = useStore();
  return (
    <div>
      <h1>{bears} bears</h1>
      <button onClick={increase}>Increase</button>
    </div>
  );
}

使用 createStore 和 subscribe 在非 React 环境中管理状态

createStore 是 Zustand 库中的另一个 API,用于创建不依赖 React 的 store。它返回一个 store 对象,这个对象可以在任何地方使用,而不仅仅是 React 组件中。适用于需要在非 React 环境中使用的场景,例如在服务端、测试或其他框架中。

🚀 使用示例

示例 1: 基础方法
import { createStore } from 'zustand/vanilla';

type BearState = {
  bears: number;
  increase: () => void;
};

const bearStore = createStore<BearState>((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
}));

// 直接使用 store
bearStore.getState().increase();
console.log(bearStore.getState().bears); // 1

// 可以结合 React Hook 使用
import { useStore } from 'zustand';

const useBearStore = () => useStore(bearStore);

export default function BearCounter() {
  const { bears, increase } = useBearStore();
  return (
    <div>
      <h1>{bears} bears</h1>
      <button onClick={increase}>Increase</button>
    </div>
  );
}
示例 2: 用上 subscribe 函数监听状态变化
import { createStore, subscribe } from 'zustand/vanilla';

type State = {
  value: number;
  update: (newValue: number) => void;
};

const store = createStore<State>((set) => ({
  value: 0,
  update: (newValue) => set((state) => ({ value: newValue })),
}));

// 使用 subscribe 监听状态变化
subscribe(store, (state) => {
  console.log(`Value updated to: ${state.value}`);
});

// 更新状态
store.update(10);

示例 3: get, set
import { createStore } from "zustand/vanilla";

// 定义状态
export type ThemeState = {
  themeMode: string;
  lang: string;
  counter: number;
};

// 定义状态方法
export type ThemeStateActions = {
  changeThemeMode: (theme: string) => void;
  resetThemeMode: () => void;
  changeLanguage: (lang: string) => void;
  resetLanguage: () => void;
  incrementCount: (num: number) => number;
  decrementCount: (num: number) => number;
};

// 状态和方法的组合
export type ThemeStore = ThemeState & ThemeStateActions;

const DEFAULT_THEME_MODE = "light";
const DEFAULT_LANG = "en";
const DEFAULT_COUNTER = 0;

// 定义默认状态
export const defaultThemeState: ThemeState = {
  counter: DEFAULT_COUNTER,
  lang: DEFAULT_LANG,
  themeMode: DEFAULT_THEME_MODE,
};

// 创建 store
export const createThemeStore = (initState: ThemeState = defaultThemeState) => {
  return createStore<ThemeStore>((set, get) => ({
    ...initState,
    changeThemeMode: (theme: string) => set(() => ({ themeMode: theme })),
    resetThemeMode: () => set(() => ({ themeMode: DEFAULT_THEME_MODE })),
    changeLanguage: (lang: string) => set(() => ({ lang })),
    resetLanguage: () => set(() => ({ lang: DEFAULT_LANG })),
    incrementCount: (num: number) => {
      set((state) => ({ counter: (state.counter += num) }));
      return get().counter;
    },
    decrementCount: (num: number) => {
      set((state) => ({ counter: (state.counter -= num) }));
      return get().counter;
    },
  }));
};

在 React 组件中使用useStore

import { useStore as useZustandStore } from 'zustand';

const useMyStore = () => useZustandStore(store);

const Component = () => {
  const { value, update } = useMyStore();
  return (
    <div>
      <p>Value: {value}</p>
      <button onClick={() => update(20)}>Update to 20</button>
    </div>
  );
};

📝 总结

  • create:返回一个 React Hook,适合在 React 组件中使用。
  • createStore:返回一个 store 对象,不依赖 React,可以在任何地方使用。

在你的具体场景中,如果你需要在 React 组件中方便地访问和操作状态,建议使用 create。如果你需要在非 React 环境中使用 store,或者需要共享 store 对象,建议使用 createStore
useStoresubscribe等函数进一步增强了其灵活性和可用性。Zustand 的简洁性和强大功能使其成为现代前端开发中状态管理的理想选择。

📚 参考文献