restate / v1.0.0
Salva quando decidi tu
Conserva uno store in IndexedDB o MMKV, caricalo una volta all’avvio, salva in modo esplicito o automatico e mostra le modifiche non salvate.
In questa pagina
Dichiara uno store salvatoAttendi una volta all’avvioSalva, annulla e reimpostaMostra le modifiche non salvate e l’avanzamentoProvaloSalva in automaticoPrima di chiudere la paginaGestisci gli errori di archiviazioneDichiara uno store salvato
Sostituisci restate con persistedRestate e dagli una key. I componenti continuano a usare lo stesso hook e lo stesso set.
Il valore salvato viene ripristinato in automatico dopo la creazione. Modificare cambia la memoria; non viene scritto nulla finché non salvi o attivi autoSave.
import { persistedRestate } from '@kkwaenggwari/restate';
export const useDraft = persistedRestate('', {
key: 'article-draft',
validate: (value) => typeof value === 'string',
});Attendi una volta all’avvio
Nell’entry point del client importa l’app e i suoi store, poi attendi restateManager.ready prima del render. Da lì i componenti possono leggere direttamente i valori salvati.
Un archivio non disponibile, come durante il rendering sul server o in un browser che lo blocca, non è un errore: quegli store funzionano in memoria. ready viene rifiutato solo quando i record non possono essere letti, migrati o validati.
import { createRoot } from 'react-dom/client';
import { restateManager } from '@kkwaenggwari/restate';
import App from './App';
async function start() {
const root = createRoot(document.getElementById('root'));
try {
await restateManager.ready;
root.render(<App />);
} catch (error) {
root.render(<p>Could not load saved data.</p>);
console.error(error);
}
}
start();Salva, annulla e reimposta
save scrive il valore attuale, restore torna al valore salvato e resetAll svuota sia la memoria sia l’archivio. Ognuno restituisce una Promise.
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removedMostra le modifiche non salvate e l’avanzamento
useStatus si ri-renderizza quando cambia lo stato di persistenza. dirty è true finché la memoria differisce dall’ultimo valore caricato, salvato o ripristinato. operation indica l’operazione di archiviazione in corso.
Passa un selector per ri-renderizzare solo quando cambia un campo.
function SaveButton() {
const { dirty, operation, error } = useDraft.useStatus();
const saving = operation === 'save';
return (
<>
<button disabled={!dirty || saving} onClick={() => useDraft.save().catch(() => {})}>
{saving ? 'Saving…' : 'Save'}
</button>
{error != null && <p>Could not save your draft.</p>}
</>
);
}Provalo
Scrivi, aumenta la latenza dell’archivio e salva. Riproduci di nuovo l’esempio per vedere ripristinata la bozza salvata.
Preparazione dell’esempio…
Salva in automatico
Per impostazioni e bozze che devono sempre persistere, attivalo una volta. autoSave: true salva dopo ogni modifica; { delayMs } aspetta che le modifiche si fermino.
Una raffica di modifiche diventa una sola scrittura, e tornare al valore salvato non scrive nulla. Gli errori compaiono in status().error. Uno scope di un componente scrive la modifica in sospeso quando viene smontato.
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });
export const useDraft = persistedRestate('', {
key: 'article-draft',
autoSave: { delayMs: 500 },
});Prima di chiudere la pagina
Leggi lo stesso stato fuori da React. Avvisa prima di uscire se ci sono modifiche non salvate, oppure salva tutto quando la pagina viene nascosta.
window.addEventListener('beforeunload', (event) => {
if (useDraft.status().dirty) event.preventDefault();
});
window.addEventListener('pagehide', () => {
restateManager.saveAll();
});Gestisci gli errori di archiviazione
Gli errori di archiviazione rifiutano la Promise dell’operazione. Ogni errore di restate ha un code e, per gli store salvati, la key del record.
try {
await useDraft.save();
} catch (error) {
if (error.code === 'STORAGE_UNAVAILABLE') showNotice('Saving is off in this browser.');
else if (error.code === 'STORAGE_VALUE_TOO_LARGE') showNotice('This draft is too large.');
else showNotice(`Could not save "${error.key ?? 'draft'}".`);
}