restate / v1.0.0
Zapisuj, kiedy zdecydujesz
Przechowuj magazyn w IndexedDB lub MMKV, wczytuj go raz przy starcie, zapisuj jawnie lub automatycznie i pokazuj niezapisane edycje.
Na tej stronie
Zadeklaruj zapisywany magazynPoczekaj raz przy starcieZapisz, cofnij i zresetujPokazuj niezapisane edycje i postępWypróbujZapisuj automatyczniePrzed zamknięciem stronyObsługuj błędy pamięciZadeklaruj zapisywany magazyn
Zamień restate na persistedRestate i nadaj mu key. Komponenty dalej używają tego samego hooka i tego samego set.
Zapisana wartość jest przywracana automatycznie po utworzeniu. Edycja zmienia pamięć; nic nie jest zapisywane, dopóki nie zapiszesz lub nie włączysz autoSave.
import { persistedRestate } from '@kkwaenggwari/restate';
export const useDraft = persistedRestate('', {
key: 'article-draft',
validate: (value) => typeof value === 'string',
});Poczekaj raz przy starcie
W punkcie wejścia klienta zaimportuj aplikację i jej magazyny, a następnie poczekaj na restateManager.ready przed renderem. Od tej chwili komponenty mogą od razu czytać zapisane wartości.
Niedostępna pamięć, jak przy renderowaniu na serwerze lub w przeglądarce, która ją blokuje, nie jest błędem: takie magazyny działają w pamięci operacyjnej. ready jest odrzucane tylko wtedy, gdy rekordów nie da się odczytać, zmigrować lub zwalidować.
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();Zapisz, cofnij i zresetuj
save zapisuje bieżącą wartość, restore wraca do zapisanej, a resetAll czyści i pamięć, i magazyn trwały. Każda zwraca Promise.
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removedPokazuj niezapisane edycje i postęp
useStatus renderuje się ponownie, gdy zmienia się status zapisu. dirty ma wartość true, dopóki pamięć różni się od ostatnio wczytanej, zapisanej lub przywróconej wartości. operation wskazuje bieżącą operację na pamięci.
Przekaż selector, by renderować ponownie tylko przy zmianie jednego pola.
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>}
</>
);
}Wypróbuj
Pisz, zwiększ opóźnienie pamięci i zapisz. Odtwórz przykład ponownie, by zobaczyć przywrócony szkic.
Przygotowywanie przykładu…
Zapisuj automatycznie
Dla ustawień i szkiców, które zawsze mają się zapisywać, włącz to raz. autoSave: true zapisuje po każdej zmianie; { delayMs } czeka, aż edycje ustaną.
Seria edycji staje się jednym zapisem, a powrót do zapisanej wartości niczego nie zapisuje. Błędy pojawiają się w status().error. Zakres komponentu zapisuje oczekującą edycję przy odmontowaniu.
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });
export const useDraft = persistedRestate('', {
key: 'article-draft',
autoSave: { delayMs: 500 },
});Przed zamknięciem strony
Odczytuj ten sam stan poza React. Ostrzegaj przed wyjściem, jeśli są niezapisane edycje, albo zapisz wszystko, gdy strona zostaje ukryta.
window.addEventListener('beforeunload', (event) => {
if (useDraft.status().dirty) event.preventDefault();
});
window.addEventListener('pagehide', () => {
restateManager.saveAll();
});Obsługuj błędy pamięci
Błędy pamięci odrzucają Promise operacji. Każdy błąd restate ma code, a w zapisywanych magazynach także key rekordu.
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'}".`);
}