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ágina
Declare 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 armazenamentoDeclare 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.
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.
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.
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removedMostre 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.
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.
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.
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.
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'}".`);
}