restate / v1.0.0

State milik komponen

Beri setiap dokumen, dialog, atau permintaan store sendiri yang dibuat bersama komponen dan dilepas setelah ia unmount.

Di halaman iniuseRestateScopeAturan factoryNilai awal dari propsServer renderingMenunggu data tersimpan dokumenCobaPemilik di luar React

useRestateScope

Factory mendeklarasikan store dan mengembalikannya. restate menyimpan hasilnya antar render dan menghancurkan scope setelah komponen unmount. Tidak perlu menulis fungsi penutup atau effect pembersihan.

Dua elemen Document punya state terpisah. Untuk membagikan dokumen ke anak-anaknya, teruskan hook yang dikembalikan lewat props atau context Anda sendiri.

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

function Document() {
  const { useDraft, useSelection } = useRestateScope((scope) => ({
    useDraft: restate('', { scope }),
    useSelection: restate(0, { scope }),
  }));
  const text = useDraft();
  const selection = useSelection();

  return (
    <section>
      <input value={text} onChange={(event) => useDraft.set(event.target.value)} />
      <button onClick={() => useSelection.set((n) => n + 1)}>Selection: {selection}</button>
    </section>
  );
}

Aturan factory

React dapat memanggil factory lebih dari sekali dan membuang hasilnya, jadi jaga agar sinkron dan murni.

  • Deklarasikan store di dalam factory; panggil hook yang dikembalikan di tingkat teratas komponen.
  • Props awal dibaca sekali, seperti pada inisialisasi useState.
  • Beri komponen key saat dokumen lain membutuhkan state yang baru.
  • Tanpa factory, useRestateScope() mengembalikan scope stabil untuk store yang Anda buat nanti di effect atau handler.

Nilai awal dari props

Gunakan props sebagai nilai awal, dan key React untuk memulai ulang dengan dokumen lain.

JavaScript / JSX
function Editor({ document }) {
  // The initial value is captured once, like a useState initializer.
  const useTitle = useRestateScope((scope) => restate(document.title, { scope }));
  const title = useTitle();
  return <input value={title} onChange={(event) => useTitle.set(event.target.value)} />;
}

// A different document gets fresh state.
<Editor key={document.id} document={document} />;

Server rendering

Muat data di route server dan teruskan sebagai prop. Nilai awal sekaligus menjadi snapshot server. Di Next.js App Router, hook ini berada di Client Component, yang tetap dirender di server.

JavaScript / JSX
'use client';

import { restate, useRestateScope } from '@kkwaenggwari/restate';

export default function Profile({ user }) {
  const useProfile = useRestateScope((scope) => restate(user, { scope }));
  const profile = useProfile();
  return <p>{profile.name}</p>;
}

Menunggu data tersimpan dokumen

Store tersimpan dalam scope mulai memulihkan saat komponen di-commit di klien dan bukan bagian dari restateManager.ready global. Tunggu manager.ready milik scope itu sendiri di dalam batas pemuatan.

JavaScript / JSX
import { useEffect, useState } from 'react';
import { persistedRestate, useRestateScope } from '@kkwaenggwari/restate';

function Document({ documentId }) {
  const { manager, useDraft } = useRestateScope((scope) => ({
    manager: scope.manager,
    useDraft: persistedRestate('', { scope, namespace: 'documents', key: documentId }),
  }));
  const [state, setState] = useState('loading');

  useEffect(() => {
    let active = true;
    manager.ready.then(
      () => active && setState('ready'),
      () => active && setState('error'),
    );
    return () => {
      active = false;
    };
  }, [manager]);

  if (state === 'error') return <p>Could not load this document.</p>;
  if (state === 'loading') return <p>Loading document…</p>;
  return <Editor useDraft={useDraft} />;
}

Coba

Buka dan tutup dokumen, lalu lihat bagaimana state-nya dimulai ulang.

Menyiapkan contoh…

Pemilik di luar React

Saat state dimiliki sebuah service atau permintaan server, buat scope sendiri dan panggil destroy() di akhir. Menghancurkan scope tidak pernah menghapus catatan tersimpan.

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

export function createDocument(documentId) {
  const scope = createRestateScope();
  const useDraft = persistedRestate('', {
    scope,
    namespace: 'documents',
    key: documentId,
  });
  return {
    useDraft,
    manager: scope.manager,
    save: () => scope.manager.saveAll(),
    destroy: () => scope.destroy(),
  };
}

Cari dokumentasi

Cari di judul, deskripsi, dan isi semua panduan.