状态持久化
@pinia-react/persistedstate 是 Pinia-React 的独立同步持久化插件,让选中的状态在刷新页面后保留。从浏览器 localStorage 和 JSON 默认配置开始,再按需增加设置。
- Store 首次创建时恢复,后续每次真实状态提交后自动保存。
- 用嵌套
pick / omit 选择字段,或按顺序拆分到多个存储策略。
- 自定义同步存储、序列化、恢复钩子和错误处理。
- 同时适用于 React、非 Hook 的
getStore 和 PiniaProvider。
先面向浏览器 SPA
下面的 React 接入适用于客户端渲染应用。服务端渲染的 App Router 页面请使用独立的 Next.js Cookie 适配器,默认 localStorage 插件不是 SSR 适配器。不要保存密码或敏感凭证。
安装
在已有 React 应用中,同时安装核心库和插件:
pnpm add pinia-react @pinia-react/persistedstate
1. 为 Store 启用持久化
src/stores/settings.ts
import { defineStore } from 'pinia-react'
export const { useSettingsStore, getSettingsStore } = defineStore('settings', {
state: () => ({ theme: 'light', compact: false }),
actions: {
toggleTheme() {
this.theme = this.theme === 'light' ? 'dark' : 'light'
}
},
persist: true
})
2. 在创建 Store 前注册插件
客户端渲染的 React 应用可以直接在 Provider 上注册:
src/main.tsx
import { createRoot } from 'react-dom/client'
import { PiniaProvider } from 'pinia-react'
import persistedState from '@pinia-react/persistedstate'
import { App } from './App'
const root = document.getElementById('root')
if (!root) throw new Error('Missing #root element')
createRoot(root).render(
<PiniaProvider plugins={[persistedState]}>
<App />
</PiniaProvider>
)
插件注册早于 Provider 内的 Store 创建。plugins 仅在初始化时生效,重渲染不会重复注册或重新恢复。已有 initialStores 仍需提供完整快照;注册插件不改变原有快照和实例隔离语义。不要重复注册同一个插件。
3. 照常读取和修改
src/App.tsx
import { useSettingsStore } from './stores/settings'
export function App() {
const settings = useSettingsStore()
return (
<button onClick={() => settings.toggleTheme()}>
Theme: {settings.theme}
</button>
)
}
点击按钮后刷新页面,可以看到状态保留。浏览器中的 settings key 内容例如:
{"theme":"dark","compact":false}
已有数据会在首次返回 Store 前同步恢复。key 不存在时保留工厂默认值,不会立即写入。后续 Action(包括 await 后的修改)、两种 $patch、$reset 和 DevTools 提交都会触发保存;Getter 本身不参与持久化。
不使用 Provider 或 Hook
以下是另一种入口,不要与前面的 Provider 方案重复初始化:
src/non-hook.ts
import { createPinia } from 'pinia-react'
import persistedState from '@pinia-react/persistedstate'
import { getSettingsStore } from './stores/settings'
createPinia().use(persistedState)
const settings = getSettingsStore()
settings.toggleTheme()
先注册,再调用 getStore / useStore;后注册的插件不会补装到已经创建的 Store。不同 Pinia / Provider 隔离内存状态,但不会隔离刻意共用的外部 storage key。
接下来读什么
| 目标 |
文档 |
| 更换 key、存储、序列化或筛选字段 |
配置 |
| 设置全局默认值、多策略或手动保存与恢复 |
进阶用法 |
| 理解补全、回调推导与配置抽取 |
TypeScript |
| 理解序列化、异常与服务端边界 |
限制与注意事项 |
本指南借鉴 pinia-plugin-persistedstate 的内容组织方式;示例和行为以 Pinia-React 自身契约为准,不包含 Vue / Nuxt 集成。
需要服务端首屏偏好时,阅读 Next.js:Cookie 持久化。
操作 API 演示
在仓库根目录运行 pnpm playground-react,体验默认插件与工厂、筛选、多策略、序列化、手动方法、钩子、错误和 DevTools;运行 pnpm playground-nextjs,体验 Cookie 快照、惰性 Store、显式恢复和可控制的延迟水合。两者都显示存储和事件日志,逐项操作说明见仓库 packages/playground/PERSISTENCE_DEMOS.md。