restate / v1.0.0
Enregistrer quand vous le décidez
Conservez un store dans IndexedDB ou MMKV, chargez-le une fois au démarrage, enregistrez explicitement ou automatiquement et affichez les modifications non enregistrées.
Sur cette page
Déclarer un store enregistréAttendre une fois au démarrageEnregistrer, annuler et réinitialiserAfficher les modifications non enregistrées et la progressionEssayerEnregistrer automatiquementAvant la fermeture de la pageGérer les erreurs de stockageDéclarer un store enregistré
Remplacez restate par persistedRestate et donnez-lui une key. Les composants continuent d’utiliser le même hook et le même set.
La valeur enregistrée est restaurée automatiquement après la création. Modifier change la mémoire ; rien n’est écrit tant que vous n’enregistrez pas ou n’activez pas autoSave.
import { persistedRestate } from '@kkwaenggwari/restate';
export const useDraft = persistedRestate('', {
key: 'article-draft',
validate: (value) => typeof value === 'string',
});Attendre une fois au démarrage
Au point d’entrée client, importez l’application et ses stores, puis attendez restateManager.ready avant le rendu. Les composants peuvent alors lire directement les valeurs enregistrées.
Un stockage indisponible, par exemple pendant le rendu serveur ou dans un navigateur qui le bloque, n’est pas un échec : ces stores fonctionnent en mémoire. ready n’est rejeté que lorsque des enregistrements ne peuvent pas être lus, migrés ou validés.
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();Enregistrer, annuler et réinitialiser
save écrit la valeur actuelle, restore revient à la valeur enregistrée et resetAll vide à la fois la mémoire et le stockage. Chacun renvoie une Promise.
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removedAfficher les modifications non enregistrées et la progression
useStatus se re-rend quand le statut de persistance change. dirty vaut true tant que la mémoire diffère de la dernière valeur chargée, enregistrée ou restaurée. operation nomme l’opération de stockage en cours.
Passez un selector pour ne re-rendre que lorsqu’un champ change.
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>}
</>
);
}Essayer
Tapez, augmentez la latence du stockage et enregistrez. Rejouez l’exemple pour voir le brouillon enregistré restauré.
Préparation de l’exemple…
Enregistrer automatiquement
Pour les réglages et brouillons qui doivent toujours persister, activez-le une fois. autoSave: true enregistre après chaque changement ; { delayMs } attend que les changements marquent une pause.
Une rafale de changements donne une seule écriture, et revenir à la valeur enregistrée n’écrit rien. Les échecs apparaissent dans status().error. Un scope propre à un composant écrit la modification en attente lors de son démontage.
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });
export const useDraft = persistedRestate('', {
key: 'article-draft',
autoSave: { delayMs: 500 },
});Avant la fermeture de la page
Lisez le même statut en dehors de React. Prévenez avant de quitter s’il reste des modifications non enregistrées, ou enregistrez tout quand la page est masquée.
window.addEventListener('beforeunload', (event) => {
if (useDraft.status().dirty) event.preventDefault();
});
window.addEventListener('pagehide', () => {
restateManager.saveAll();
});Gérer les erreurs de stockage
Les erreurs de stockage rejettent la Promise de l’opération. Chaque erreur restate a un code et, pour les stores enregistrés, la key de l’enregistrement.
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'}".`);
}