restate / v1.0.0

Състояние, което принадлежи на компонент

Дайте на всеки документ, диалог или заявка собствени store, които се създават с компонента и се освобождават след демонтирането му.

На тази страницаuseRestateScopeПравила за factoryНачални стойности от propsРендериране на сървъраИзчакване на запазените данни на документОпитайтеСобственици извън React

useRestateScope

Factory декларира store и ги връща. restate пази резултата между рендерите и унищожава scope след демонтиране на компонента. Няма функция за затваряне или effect за почистване, които да пишете.

Два елемента Document имат независими състояния. За да споделите документ с дъщерни компоненти, подайте върнатите hooks чрез props или собствен контекст.

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

Правила за factory

React може да извика factory повече от веднъж и да изхвърли резултатите, затова я дръжте синхронна и чиста.

  • Декларирайте store във factory; извиквайте върнатите hooks на най-горното ниво на компонента.
  • Началните props се четат веднъж, както в инициализатор на useState.
  • Дайте на компонента key, когато друг документ се нуждае от ново състояние.
  • Без factory useRestateScope() връща стабилен scope за store, които създавате по-късно в effects или обработчици.

Начални стойности от props

Използвайте props като начални стойности и key на React, за да започнете отначало с друг документ.

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

Рендериране на сървъра

Заредете данните в сървърния маршрут и ги подайте като prop. Началната стойност служи и като моментна снимка от сървъра. В App Router на Next.js този hook е в Client Component, който пак се рендерира на сървъра.

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

Изчакване на запазените данни на документ

Запазваните store в scope започват възстановяване след commit на компонента в клиента и не са част от глобалния restateManager.ready. Изчакайте собствения manager.ready на scope в граница за зареждане.

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

Опитайте

Отваряйте и затваряйте документи и вижте как състоянието им започва отначало.

Подготовка на примера…

Собственици извън React

Когато състоянието принадлежи на услуга или на заявка към сървъра, създайте scope сами и извикайте destroy() накрая. Унищожаването на scope никога не изтрива запазени записи.

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

Търсене в документацията

Търсене в заглавията, описанията и текста на всички ръководства.