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 stronieZadeklaruj zapisywany magazynPoczekaj raz przy starcieZapisz, cofnij i zresetujPokazuj niezapisane edycje i postępWypróbujZapisuj automatyczniePrzed zamknięciem stronyObsługuj błędy pamięci

Zadeklaruj 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.

JavaScript / JSX
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ć.

JavaScript / JSX
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.

JavaScript / JSX
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removed

Pokazuj 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.

JavaScript / JSX
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.

JavaScript / JSX
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.

JavaScript / JSX
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.

JavaScript / JSX
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'}".`);
}

Szukaj w dokumentacji

Przeszukuj tytuły, opisy i treść wszystkich przewodników.