Files
simple-react-app-kit/packages/preferences/docs/zh-Hans/advanced/lifecycle.mdx
T

58 lines
1.9 KiB
Plaintext
Raw Normal View History

---
title: 生命周期与持久化
description: 协调 SSR、异步持久化、浏览器同步和外部输入校验。
order: 20
toc:
- id: server-snapshots
title: 服务端快照
- id: persist-updates
title: 持久化更新
- id: preference-effects
title: 偏好副作用
- id: validate-updates
title: 校验更新
---
## 服务端快照 {#server-snapshots}
Provider 创建 Store 时会捕获 `initialPreferences`。它会一直作为服务端和水合快照;之后改变这个属性不会重置本地偏好。当应用有意切换到另一套偏好身份时,应重新挂载 Provider。
## 持久化更新 {#persist-updates}
`onPreferenceChange` 只在值确实发生变化时运行。它可以返回 Promise,但持久化过程不会阻塞本地更新。重试、错误和回滚行为应在应用边界处理。
## 偏好副作用 {#preference-effects}
副作用用于连接偏好与 React 之外的 API:
```tsx
const documentEffects = [
{
layoutEffect: ({ preferences }) => {
document.documentElement.dataset.theme = preferences["theme-mode"]
},
effect: ({ store }) => {
const media = window.matchMedia("(prefers-color-scheme: dark)")
const listener = () => synchronizeTheme(store.getSnapshot(), media)
media.addEventListener("change", listener)
return () => media.removeEventListener("change", listener)
},
},
] satisfies readonly PreferenceEffect[]
```
必须在绘制前完成的 DOM 变更使用 `layoutEffect`,订阅使用 `effect`。副作用数组的引用应保持稳定,因为快照或数组变化时,回调和清理函数都会重新运行。
## 校验更新 {#validate-updates}
在接受无类型边界的数据前,使用相同的 Definitions 创建类型守卫:
```ts
const isPreferenceUpdate = createPreferenceUpdateGuard(definitions)
if (isPreferenceUpdate(payload)) {
await savePreference(payload)
}
```