restate / v1.0.0
Stato che appartiene a un componente
Dai a ogni documento, finestra di dialogo o richiesta i propri store, creati con il componente e rilasciati dopo il suo smontaggio.
In questa pagina
useRestateScopeRegole della factoryValori iniziali dalle propsRendering sul serverAttendi i dati salvati di un documentoProvaloProprietari fuori da ReactuseRestateScope
La factory dichiara gli store e li restituisce. restate conserva il risultato tra un render e l’altro e distrugge lo scope dopo lo smontaggio del componente. Non c’è nessuna funzione di chiusura né effect di pulizia da scrivere.
Due elementi Document hanno stati indipendenti. Per condividere un documento con i figli, passa gli hook restituiti tramite props o il tuo 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>
);
}Regole della factory
React può chiamare la factory più volte e scartarne i risultati, quindi mantienila sincrona e pura.
- Dichiara gli store nella factory; chiama gli hook restituiti al livello superiore del componente.
- Le props iniziali vengono lette una volta, come in un inizializzatore di useState.
- Dai una key al componente quando un altro documento ha bisogno di uno stato nuovo.
- Senza factory, useRestateScope() restituisce uno scope stabile per gli store che crei più tardi, in effect o handler.
Valori iniziali dalle props
Usa le props come valori iniziali e una key di React per ricominciare con un altro documento.
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} />;Rendering sul server
Carica i dati nella route del server e passali come prop. Il valore iniziale fornisce anche lo snapshot del server. Nell’App Router di Next.js questo hook va in un Client Component, che viene comunque renderizzato sul server.
'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>;
}Attendi i dati salvati di un documento
Gli store salvati in uno scope iniziano il ripristino dopo il commit del componente sul client e non fanno parte del restateManager.ready globale. Attendi il manager.ready proprio dello scope in un boundary di caricamento.
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} />;
}Provalo
Apri e chiudi documenti e guarda il loro stato ripartire da zero.
Preparazione dell’esempio…
Proprietari fuori da React
Quando lo stato appartiene a un servizio o a una richiesta del server, crea tu lo scope e chiama destroy() alla fine. Distruggere uno scope non elimina mai i record salvati.
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(),
};
}