restate / v1.0.0

Salve quando você decidir

Guarde um store no IndexedDB ou no MMKV, carregue uma vez na inicialização, salve de forma explícita ou automática e mostre as alterações não salvas.

Nesta páginaDeclare um store salvoEspere uma vez na inicializaçãoSalvar, desfazer e redefinirMostre alterações não salvas e o progressoExperimenteSalve automaticamenteAntes de fechar a páginaTrate erros de armazenamento

Declare um store salvo

Troque restate por persistedRestate e dê a ele uma key. Os componentes continuam usando o mesmo hook e o mesmo set.

O valor salvo é restaurado automaticamente depois da criação. Editar muda a memória; nada é gravado até você salvar ou ligar o autoSave.

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  validate: (value) => typeof value === 'string',
});

Espere uma vez na inicialização

Na entrada do cliente, importe o app e seus stores e espere restateManager.ready antes de renderizar. Depois disso, os componentes podem ler os valores salvos diretamente.

Armazenamento indisponível, como na renderização no servidor ou em um navegador que o bloqueia, não é falha: esses stores funcionam em memória. ready só é rejeitado quando registros não podem ser lidos, migrados ou validados.

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();

Salvar, desfazer e redefinir

save grava o valor atual, restore volta ao valor salvo e resetAll limpa memória e armazenamento. Todos retornam uma 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

Mostre alterações não salvas e o progresso

useStatus renderiza de novo quando o status de persistência muda. dirty é true enquanto a memória difere do último valor carregado, salvo ou restaurado. operation indica a operação de armazenamento em andamento.

Passe um selector para renderizar de novo só quando um campo mudar.

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>}
    </>
  );
}

Experimente

Digite, aumente a latência do armazenamento e salve. Reproduza o exemplo de novo para ver o rascunho salvo ser restaurado.

Preparando o exemplo…

Salve automaticamente

Para configurações e rascunhos que devem persistir sempre, ative uma vez. autoSave: true salva depois de cada mudança; { delayMs } espera as mudanças pararem.

Uma rajada de mudanças vira uma única gravação, e voltar ao valor salvo não grava nada. As falhas aparecem em status().error. Um scope de componente grava a mudança pendente ao ser desmontado.

JavaScript / JSX
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  autoSave: { delayMs: 500 },
});

Antes de fechar a página

Leia o mesmo status fora do React. Avise antes de sair se houver alterações não salvas, ou salve tudo quando a página for ocultada.

JavaScript / JSX
window.addEventListener('beforeunload', (event) => {
  if (useDraft.status().dirty) event.preventDefault();
});

window.addEventListener('pagehide', () => {
  restateManager.saveAll();
});

Trate erros de armazenamento

Erros de armazenamento rejeitam a Promise da operação. Todo erro do restate tem um code e, nos stores salvos, a key do registro.

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

Pesquisar na documentação

Pesquisa em títulos, descrições e texto de todos os guias.