restate / v1.0.0

저장은 원할 때

스토어를 IndexedDB나 MMKV에 보관하고, 시작할 때 한 번 불러오고, 직접 또는 자동으로 저장하고, 저장하지 않은 변경을 보여 줍니다.

이 페이지에서저장 스토어 선언시작할 때 한 번 기다리기저장·되돌리기·초기화미저장 변경과 진행 상태 보여 주기직접 해 보기자동으로 저장하기페이지를 닫기 전에저장소 오류 처리

저장 스토어 선언

restate를 persistedRestate로 바꾸고 key를 주세요. 컴포넌트는 같은 훅과 set을 그대로 씁니다.

저장된 값은 만든 뒤 자동으로 복원됩니다. 편집은 메모리만 바꾸며, save를 부르거나 autoSave를 켜기 전에는 아무것도 쓰지 않습니다.

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

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

시작할 때 한 번 기다리기

클라이언트 진입점에서 앱과 스토어를 import한 뒤, 렌더하기 전에 restateManager.ready를 기다리세요. 그러면 컴포넌트는 저장된 값을 바로 읽습니다.

서버 렌더링이나 막힌 브라우저처럼 저장소를 쓸 수 없는 경우는 실패가 아닙니다. 그 스토어는 메모리로 동작합니다. ready는 기록을 읽거나 마이그레이션하거나 검증하지 못했을 때만 거부됩니다.

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

저장·되돌리기·초기화

save는 현재 값을 쓰고, restore는 저장된 값으로 돌아가고, resetAll은 메모리와 저장소를 모두 비웁니다. 모두 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

미저장 변경과 진행 상태 보여 주기

useStatus는 저장 상태가 바뀔 때 다시 렌더합니다. dirty는 메모리가 마지막으로 불러오거나 저장하거나 복원한 값과 다를 때 true입니다. operation은 실행 중인 저장소 작업의 이름입니다.

selector를 넘기면 필드 하나가 바뀔 때만 렌더합니다.

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

직접 해 보기

입력하고, 저장소 지연을 늘리고, 저장하세요. 예제를 다시 실행하면 저장한 초안이 복원됩니다.

예제를 준비하는 중…

자동으로 저장하기

항상 저장해야 하는 설정이나 초안은 한 번만 켜 두세요. autoSave: true는 변경마다 저장하고, { delayMs }는 변경이 멈출 때까지 기다립니다.

연속된 변경은 한 번의 쓰기가 되고, 저장된 값으로 되돌린 변경은 쓰지 않습니다. 실패는 status().error에 나타납니다. 컴포넌트가 소유한 scope는 언마운트할 때 대기 중인 변경을 씁니다.

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

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

페이지를 닫기 전에

같은 상태를 React 밖에서도 읽습니다. 저장하지 않은 변경이 있으면 떠나기 전에 경고하거나, 페이지가 숨겨질 때 모두 저장하세요.

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

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

저장소 오류 처리

저장소 오류는 해당 작업의 Promise를 거부합니다. 모든 restate 오류에는 code가 있고, 저장 스토어라면 기록의 key도 있습니다.

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

문서 검색

모든 가이드의 제목·설명·본문을 검색합니다.