restate / v1.0.0
State die bij een component hoort
Geef elk document, elke dialoog of elk verzoek eigen stores, aangemaakt met het component en vrijgegeven na de unmount.
Op deze pagina
useRestateScopeRegels voor de factoryBeginwaarden uit propsServer-renderingWacht op de opgeslagen data van een documentProbeer hetEigenaren buiten ReactuseRestateScope
De factory declareert stores en geeft ze terug. restate bewaart het resultaat tussen renders en vernietigt de scope na de unmount van het component. Er is geen sluitfunctie of opruim-effect om te schrijven.
Twee Document-elementen hebben onafhankelijke state. Om een document met kinderen te delen, geef je de teruggegeven hooks door via props of je eigen context.
import { restate, useRestateScope } from '@kkwaenggwari/restate';
function Document() {
const { useDraft, useSelection } = useRestateScope((scope) => ({
useDraft: restate('', { scope }),
useSelection: restate(0, { scope }),
}));
const text = useDraft();
const selection = useSelection();
return (
<section>
<input value={text} onChange={(event) => useDraft.set(event.target.value)} />
<button onClick={() => useSelection.set((n) => n + 1)}>Selection: {selection}</button>
</section>
);
}Regels voor de factory
React kan de factory vaker aanroepen en resultaten weggooien, dus houd hem synchroon en puur.
- Declareer stores in de factory; roep de teruggegeven hooks aan op het hoogste niveau van het component.
- Begin-props worden één keer gelezen, net als in een initializer van useState.
- Geef het component een key als een ander document verse state nodig heeft.
- Zonder factory geeft useRestateScope() een stabiele scope terug voor stores die je later maakt in effects of handlers.
Beginwaarden uit props
Gebruik props als beginwaarden en een React-key om opnieuw te beginnen met een ander document.
function Editor({ document }) {
// The initial value is captured once, like a useState initializer.
const useTitle = useRestateScope((scope) => restate(document.title, { scope }));
const title = useTitle();
return <input value={title} onChange={(event) => useTitle.set(event.target.value)} />;
}
// A different document gets fresh state.
<Editor key={document.id} document={document} />;Server-rendering
Laad data in de serverroute en geef die door als prop. De beginwaarde levert ook de server-snapshot. In de Next.js App Router hoort deze hook in een Client Component, dat nog steeds op de server rendert.
'use client';
import { restate, useRestateScope } from '@kkwaenggwari/restate';
export default function Profile({ user }) {
const useProfile = useRestateScope((scope) => restate(user, { scope }));
const profile = useProfile();
return <p>{profile.name}</p>;
}Wacht op de opgeslagen data van een document
Opgeslagen stores in een scope beginnen met terugzetten nadat het component op de client is gecommit, en vallen niet onder de globale restateManager.ready. Wacht op de eigen manager.ready van de scope binnen een laadgrens.
import { useEffect, useState } from 'react';
import { persistedRestate, useRestateScope } from '@kkwaenggwari/restate';
function Document({ documentId }) {
const { manager, useDraft } = useRestateScope((scope) => ({
manager: scope.manager,
useDraft: persistedRestate('', { scope, namespace: 'documents', key: documentId }),
}));
const [state, setState] = useState('loading');
useEffect(() => {
let active = true;
manager.ready.then(
() => active && setState('ready'),
() => active && setState('error'),
);
return () => {
active = false;
};
}, [manager]);
if (state === 'error') return <p>Could not load this document.</p>;
if (state === 'loading') return <p>Loading document…</p>;
return <Editor useDraft={useDraft} />;
}Probeer het
Open en sluit documenten en zie hun state opnieuw beginnen.
Voorbeeld voorbereiden…
Eigenaren buiten React
Als state bij een service of een serververzoek hoort, maak je de scope zelf aan en roep je aan het eind destroy() aan. Een scope vernietigen verwijdert nooit opgeslagen records.
import { createRestateScope, persistedRestate } from '@kkwaenggwari/restate';
export function createDocument(documentId) {
const scope = createRestateScope();
const useDraft = persistedRestate('', {
scope,
namespace: 'documents',
key: documentId,
});
return {
useDraft,
manager: scope.manager,
save: () => scope.manager.saveAll(),
destroy: () => scope.destroy(),
};
}