Files
simple-react-app-kit/packages/preferences/docs/en-US/advanced/lifecycle.mdx
T

58 lines
2.0 KiB
Plaintext
Raw Normal View History

---
title: Lifecycle and persistence
description: Coordinate SSR, asynchronous persistence, browser synchronization, and external input validation.
order: 20
toc:
- id: server-snapshots
title: Server snapshots
- id: persist-updates
title: Persist updates
- id: preference-effects
title: Preference effects
- id: validate-updates
title: Validate updates
---
## Server snapshots {#server-snapshots}
`initialPreferences` is captured when the provider creates its store. It remains the server and hydration snapshot; changing that prop later does not reset local preferences. Remount the provider when the application intentionally switches to a different preference identity.
## Persist updates {#persist-updates}
`onPreferenceChange` runs only when a value actually changes. It may return a promise, but local updates are not blocked while persistence completes. Handle retries, errors, and rollback behavior in the application boundary.
## Preference effects {#preference-effects}
Effects connect preferences to APIs outside React:
```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[]
```
Use `layoutEffect` for DOM changes that must happen before paint. Use `effect` for subscriptions. Keep the effects array reference stable because callbacks and cleanup functions run again whenever the snapshot or array changes.
## Validate updates {#validate-updates}
Create a type guard from the same definitions before accepting data from an untyped boundary:
```ts
const isPreferenceUpdate = createPreferenceUpdateGuard(definitions)
if (isPreferenceUpdate(payload)) {
await savePreference(payload)
}
```