跳转到正文
Monster Cone
返回

Zustand + IndexedDB 实战:打造可离线的前端状态管理

编辑页面

为了摆脱 Microsoft To Do 每次使用都需要修改密码登录的困扰,我决定开发一个无需登录、可离线使用的 Monster TodoList。本文将分享如何利用 Zustand 和 IndexedDB 实现高效的离线数据持久化。

1. Zustand 持久化基础

要创建一个可持久化的 Store,我们需要使用persist、createJSONStorage这两个中间件。

让我们从一个简单的 useCountStore 示例开始:

import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";

interface CountState {
  count: number;
  add: () => void;
  sub: () => void;
}

const useCountStore = create<CountState>()(
  persist(
    set => ({
      count: 0,
      add: () => set(state => ({ count: state.count + 1 })),
      sub: () => set(state => ({ count: state.count - 1 })),
    }),
    {
      name: "count", // 存储在 Storage 中的键名
      storage: createJSONStorage(() => sessionStorage), // 使用 sessionStorage 作为存储介质
    }
  )
);

persist接受两个参数:

  1. Store 定义: 即 (set, get) => ({ ... }),定义了 Store 的初始状态和 actions。
  2. 持久化配置对象: Store持久化的详细配置。

关键持久化配置如下:

还有一些其他配置可查看Zustand 官方文档 Persisting store data

2. 理解自定义持久化

在第一节我们已经知道如何配置持久化,接下来我们要自定义持久化。

const customStorage = {
  getItem: async (name: string) => { return JSON.stringify(state: {count: 0})},
  setItem: async (name: string, value: string) => {},
  removeItem: async (name: string) => {},
}

上面就是自定义持久化的基础模板。

3. 自定义持久化初始化Store

上述我们已经知道了自定义持久化配置,只需要添加相关的indexedDB的逻辑即可。

建议仅在getItem中获取indexedDB数据初始化store即可,使用indexedDB存储的有序数据不适合通过setItem持久化,建议直接操作indexedDB。

getItem中可以执行异步操作,可以发送请求获取远程数据进行初始化。


编辑页面
分享这篇文章:

上一篇
不用额外 State:Tailwind CSS 实现可编辑标题
下一篇
用 Cloudflare Workers 搭建 FCM 推送中转服务