restate / v1.0.0

Stan należący do komponentu

Daj każdemu dokumentowi, oknu dialogowemu czy żądaniu własne magazyny, tworzone z komponentem i zwalniane po jego odmontowaniu.

Na tej stronieuseRestateScopeZasady fabrykiWartości początkowe z propsRenderowanie na serwerzePoczekaj na zapisane dane dokumentuWypróbujWłaściciele poza React

useRestateScope

Fabryka deklaruje magazyny i je zwraca. restate przechowuje wynik między renderami i niszczy zakres po odmontowaniu komponentu. Nie trzeba pisać funkcji zamykającej ani efektu sprzątającego.

Dwa elementy Document mają niezależne stany. Aby udostępnić dokument dzieciom, przekaż zwrócone hooki przez props lub własny kontekst.

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

Zasady fabryki

React może wywołać fabrykę więcej niż raz i odrzucić wyniki, więc niech będzie synchroniczna i czysta.

  • Deklaruj magazyny w fabryce; wywołuj zwrócone hooki na najwyższym poziomie komponentu.
  • Początkowe props są odczytywane raz, jak w inicjalizatorze useState.
  • Nadaj komponentowi key, gdy inny dokument potrzebuje świeżego stanu.
  • Bez fabryki useRestateScope() zwraca stabilny zakres dla magazynów, które utworzysz później w efektach lub obsłudze zdarzeń.

Wartości początkowe z props

Użyj props jako wartości początkowych, a key w React, by zacząć od nowa z innym dokumentem.

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

Renderowanie na serwerze

Wczytaj dane w trasie serwera i przekaż je jako prop. Wartość początkowa służy też jako migawka serwera. W App Router Next.js ten hook trafia do Client Component, który i tak jest renderowany na serwerze.

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

Poczekaj na zapisane dane dokumentu

Zapisywane magazyny w zakresie zaczynają przywracanie po zatwierdzeniu komponentu po stronie klienta i nie są częścią globalnego restateManager.ready. Poczekaj na własny manager.ready zakresu wewnątrz granicy ładowania.

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

Wypróbuj

Otwieraj i zamykaj dokumenty i patrz, jak ich stan zaczyna się od zera.

Przygotowywanie przykładu…

Właściciele poza React

Gdy stan należy do usługi lub żądania na serwerze, utwórz zakres samodzielnie i na końcu wywołaj destroy(). Zniszczenie zakresu nigdy nie usuwa zapisanych rekordów.

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

Szukaj w dokumentacji

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