持久化

zustand 持久化中间件默认使用 JSON.strinify 和 JSON.parse 进行序列化和反序列化操作。但是这两个方法并不支持 ES6 的 Map 和 Set。因此会出现反序列化类型错误的问题。

对于这种问题,可以在自定义 storage 中[1] set, map 字段。但是更简单的是使用 superjson 来解决这个问题。

superjson 可以看作是 JSON 的等价替代物,提供了对 Map 和 Set 的支持。使用 superjson 后自定义 storage 可以设置为:

import superjson from 'superjson';

export const useAppState = create<AppState>()(
  persist(
    immer(set => ({
      repoPath: undefined,
    })),
    {
      name: 'app',
      storage: {
        getItem: async name => {
          const str = await tauriStore.get<string>(name);
          if (!str) return null;
          return superjson.parse<StorageValue<AppState>>(str);
        },
        setItem: async (name, value) => {
          const str = superjson.stringify(value);
          await tauriStore.set(name, str);
        },
        removeItem: async name => await tauriStore.delete(name),
      },
      // @ts-expect-error: no error
      partialize: s => ({
        repoPath: s.repoPath,
      }),
    },
  ),
);

immr

zustand 中自带 immr 中间件,用起来很方便:

import { immer } from 'zustand/middleware/immer';

export const useAppState = create<AppState>()(
  immer(set => ({
    projects: new Set<string>(),
    removeRepoPath: (path: string) => {
      set(s => {
        s.projects.delete(path);
      });
    },
  })),
);
Last moify: 2024-12-26 10:35:34
Build time:2025-08-18 18:43:08
Powered By asphinx