zfb
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

スコープとライフサイクル

現在のコンポーネントスコープに、セットアップ時のリソース、ブラウザでの有効化、effect、クリーンアップを登録します。

現在の所有者を取得する

同期的なコンポーネントのセットアップ中、または Show や For のファクトリ内で getScope を呼び、その関数をレンダリングしている所有者に作業を登録します。セットアップ中に直接呼んだヘルパーは同じ所有者を共有し、独立したスコープは作りません。

import type { ReadonlySignal } from "@takazudo/zfb/zudo-react";
import { getScope, signal } from "@takazudo/zfb/zudo-react";

function Clock() {
  const scope = getScope();
  const now = signal(Date.now());

  scope.onActivate(() => {
    const timer = window.setInterval(() => {
      now.value = Date.now();
    }, 1000);

    return () => window.clearInterval(timer);
  });

  return <time>{now}</time>;
}

getScope はセットアップ専用です。現在のレンダリング所有者がいない場所で呼ぶと ZR_NO_SCOPE が発生します。await を越えて所有者は維持されないため、非同期セットアップには対応しません。純粋な SDK コンストラクターは記述を作るだけなので、スコープなしでも呼べます。

セットアップと有効化を分ける

同期的なリソースのクリーンアップは onCleanup に登録します。ブラウザだけで行う起動処理は onActivate に登録し、そのコールバックから同期的なクリーンアップを返すこともできます。追跡されるブラウザの effect は effect に登録します。

function PageTitle({ title }: { title: ReadonlySignal<string> }) {
  const scope = getScope();

  scope.effect(() => {
    document.title = title.value;
  });

  return <h1>{title}</h1>;
}

有効化コールバックはブラウザでのみ、DOM のコミット後に実行されます。レンダラーはすべての ref をコールバックより前に設定します。子スコープは親より先に有効化され、兄弟は出力順、一つのスコープ内のコールバックは登録順に進みます。すべての有効化コールバックが終わった後、スケジューラーの最初の effect 段階で effect が始まります。サーバーではブラウザの有効化も effect も実行されません。

effect はコールバック中に読み取った値を追跡します。再実行前には前回のクリーンアップが追跡なしで実行されます。最後のクリーンアップはスコープの破棄時に実行されます。effect が例外を投げると報告され、古い依存関係は解除されますが、ほかの effect は続行します。

有効化に失敗すると、ランタイムはそのルートのリソースを破棄して失敗を報告します。すでに外部の状態を変えたユーザーコードは自分でクリーンアップを用意する必要があります。ランタイムは任意の副作用を取り消せません。

Promise を返すクリーンアップは無効です。クリーンアップコールバックは同期的で、スコープが有効な間に登録する必要があります。後で非同期処理を行うコールバックは提供される abort signal を使い、結果を反映する前に状態を確認してください。

破棄しても DOM は削除されない

スコープを破棄すると、所有者を無効にし、signal を abort し、キューにあるジョブを止め、子スコープを破棄します。ノードがまだ存在する間に登録の逆順でクリーンアップを実行し、最後に ref をクリアします。クリーンアップ中にエラーが起きても報告して続行します。破棄した作業は再び有効化できません。

マウント済みルートの dispose はランタイムのリソースを解放しますが、ラッパーとその DOM は残します。unmount は破棄に加え、そのハンドルが所有するノードを削除し、ラッパーは残します。zfb はラッパーの内容を自分で置き換える前に破棄を使います。ルートの削除や保留中のトリガーの取り消しで、以後の有効化を防げます。

クライアントのルートハンドルは identity と破棄状態を公開します。hydrate は既存のノードを引き継ぎ、mount は新しい子 DOM を作ります。どちらも想定される失敗を報告して null を返し、部分的に有効なハンドルは返しません。zfb はルートごとにエラーを分離するため、一つの島が壊れてもほかのルートの処理は続きます。

サーバーレンダリングは一時的なスコープグラフを所有し、エラーの場合も含め、レンダリング終了時に必ず破棄します。リクエスト固有の可変状態はモジュールレベルの変数ではなくレンダリング内に置いてください。

関連ページ

Revision History

作成更新