restate / v1.0.0

Стан, що належить компоненту

Дайте кожному документу, діалогу чи запиту власні сховища, які створюються разом із компонентом і звільняються після його демонтування.

На цій сторінціuseRestateScopeПравила фабрикиПочаткові значення з propsРендеринг на серверіОчікування збережених даних документаСпробуйтеВласники поза React

useRestateScope

Фабрика оголошує сховища й повертає їх. restate зберігає результат між рендерами й знищує область після демонтування компонента. Жодних функцій закриття чи ефектів очищення писати не треба.

Два елементи Document мають незалежні стани. Щоб передати документ дочірнім компонентам, передайте повернені хуки через 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>
  );
}

Правила фабрики

React може викликати фабрику кілька разів і відкидати результати, тож вона має бути синхронною й чистою.

  • Оголошуйте сховища у фабриці; викликайте повернені хуки на верхньому рівні компонента.
  • Початкові props читаються один раз, як в ініціалізаторі useState.
  • Задайте компоненту key, коли іншому документу потрібен новий стан.
  • Без фабрики useRestateScope() повертає стабільну область для сховищ, які ви створите пізніше — в ефектах чи обробниках.

Початкові значення з 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 цей хук розміщується в 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>;
}

Очікування збережених даних документа

Збережувані сховища в області починають відновлення після коміту компонента на клієнті й не входять до глобального restateManager.ready. Чекайте на власний manager.ready області всередині межі завантаження.

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

Коли стан належить сервісу чи серверному запиту, створіть область самі й викличте destroy() наприкінці. Знищення області ніколи не видаляє збережені записи.

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

Пошук у документації

Пошук у заголовках, описах і тексті всіх посібників.