本文へスキップ

React ​

decidekit/react にはワーカーのデサイダーの上で動くフックが 2 つあります。React は任意のピア依存(18 以降)で、使わないアプリに追加でインストールされるものはありません。Next.js 16 の React 19(next dev と next build)と、Vite 7(StrictMode)でテストしました。

tsx
"use client";
import { useState } from "react";
import { useDecider, useDecision } from "decidekit/react";

const LABELS = ["question", "bug_report", "praise"] as const;

export function Triage() {
  const { decider, status, progress } = useDecider();
  const [text, setText] = useState("");
  const { decision, pending } = useDecision(decider, text, LABELS, { minConfidence: 0.8 });

  if (status === "loading") return <p>Loading model {progress ? `${Math.round((100 * progress.loaded) / progress.total)}%` : ""}</p>;
  return (
    <>
      <textarea value={text} onChange={(e) => setText(e.target.value)} />
      <p>{pending ? "..." : decision?.choice ?? "none of these"}</p>
    </>
  );
}

useDecider(options?) ​

マウント時にワーカーのデサイダーを起動し、アンマウント時に終了します。createWorkerDecider() と同じオプションを受け取ります。ただし onProgress はフックが処理します。

{ decider, status, progress, error } を返します。

  • decider:準備ができたワーカーのデサイダー。それまでは null です。train() や decideMany() には直接使ってください。
  • status:"loading"、"ready"、"error" のどれか。
  • progress:ダウンロード中(初回の訪問のみ)のモデルファイル全体の { loaded, total } バイト。それ以外は null です。
  • error:status が "error" のときの読み込みエラー。

呼び出しごとに専用のワーカーを起動し、モデルのコピーを読み込みます。ツリーの上のほうで 1 回だけ呼び、decider を下へ渡してください(props や context)。オプションはマウント時に読みます。モデルを変えるには key で再マウントしてください。

useDecision(decider, text, using, options?) ​

text か using(ラベル、説明付きラベル、ヘッド)が変わると、debounceMs(デフォルト 150 ms)の静止のあとに判定します。その後にテキストが変わった答えは捨てるので、速く入力しても古いラベルは表示されません。

{ decision, pending, error } を返します。decision が null になるのは、最初の答えの前、decider か using が null の間、テキストが空のときです。minConfidence を渡すと、decision.choice の型は L | null になります。

using は安定させてください。コンポーネントの外の定数、state、useMemo のどれかです。レンダーごとに新しい配列を作ると、レンダーごとに判定し直します。

Next.js ​

フックはクライアントコンポーネント("use client")で使ってください。Next.js はクライアントコンポーネントもサーバーで 1 回レンダーします。フックがワーカーを起動するのはエフェクトの中だけで、サーバーでは実行されません。クロスオリジン分離のヘッダーと wasm のエイリアスをバンドラーのとおりに追加してください。