mcpField
M
meteor-react

meteor-react

github.com/meteor開発10283 回インストール5 日前に更新
リポジトリ

meteor-react について

meteor-react は、Meteor 3 アプリで React インターフェースを構築するためのスキルです。リアクティブデータ用フック、描画、ビルド設定、更新処理、ブラウザテストを案内します。

主な機能

  1. 01React ルートのマウント
  2. 02react-meteor-data フックの選択
  3. 03Tracker 対応のリスト表示
  4. 04Suspense と非同期データの扱い
  5. 05Rspack 設定と React Refresh
  6. 06UI 動作のブラウザテスト

活用シーン

  1. 01Meteor 3 の React アプリを新規作成
  2. 02購読状態に応じた画面表示
  3. 03リアクティブなタスクリストの実装
  4. 04Meteor UI のブラウザテスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/meteor/agent-skills --skill meteor-react

インストール後、Claude Code で/meteor-reactを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
build-refresh-and-testing.md
eval-cases.md
react-meteor-data.md
suspense-and-async.md

詳細

Meteor 3 向け React インターフェース

React はレンダリングとローカル UI 状態を管理し、Meteor はリアクティブデータとビルドの受け渡しを管理します。コンポーネントは認可済みデータを利用し、メソッドを呼び出します。 パブリケーションとメソッドは引き続きサーバー側が権限を持ちます。

判断フロー

  1. 新しい JavaScript アプリの場合は、meteor create --react <name> を実行します。React はデフォルトのスケルトンでもあります。TypeScript と TSX の場合は、meteor create --typescript <name> を実行します。
  2. package.json、.meteor/packages、.meteor/versions、クライアントのエントリーポイント、rspack.config.* を確認します。スケルトンと react-meteor-data のバージョンは、それぞれ独立して変更される可能性があります。
  3. Meteor.startup から createRoot を使って、React ルートを 1 つマウントします。
  4. コンポーネントには、react-meteor-data のサーフェスを 1 つ選びます。
    • 明示的な読み込み UI と同期的な Minimongo の読み取りには、クラシックフックを使います。
    • 保留中の状態とエラー状態を、上位の Suspense フォールバックと拒否境界がすでに管理している場合に限り、Suspense フックを使います。
  5. 準備状態には useSubscribe、安定したドキュメント参照を持つリアクティブなリストには useFind、その他の Tracker 値には useTracker を使います。
  6. React 固有の Rspack ルールはここで扱います。ルートエイリアス、ローダー、コード分割、キャッシュ、出力、移行に関する作業はビルドスキルに委ねます。
  7. UI の動作はブラウザーを使ったクライアントテストスイートでテストし、Tracker の計算処理やサブスクリプションを停止できるよう、レンダリングしたルートは必ずアンマウントします。

現在のスキャフォールド

meteor create --react my-app
cd my-app
meteor

現在の Meteor 3.4 以降のスキャフォールドでは、Rspack と react-meteor-data を使用します。.meteor/versions を確認してください。Meteor 3 では 3.0.0 以降が必要で、これらの例は 4.0.1 を対象としており、references/react-meteor-data.md に機能の最低バージョンが記載されています。

import { Meteor } from "meteor/meteor";
import { createRoot } from "react-dom/client";
import { App } from "/imports/ui/App";
import "/imports/ui/styles.css";

Meteor.startup(() => {
  const container = document.getElementById("react-target");
  if (!container) throw new Error("Missing #react-target");
  createRoot(container).render(<App />);
});

TypeScript では client/main.tsx と tsconfig.json を使用し、通常は rspack.config.ts も使用します。Meteor はその TypeScript 設定を直接検出します。

リアクティブデータの選択

必要なものAPI契約
サブスクリプションの準備状態クラシック useSubscribeisLoading 関数を返します。呼び出して使用します。
リアクティブなリストクラシック useFindカーソルを返します。fetch() は使いません。
ユーザー、件数、単一ドキュメント、ReactiveVarクラシック useTrackerリアクティブな値を返します。任意の副作用は避けてください。
Suspense を使った非同期値Suspense useTracker安定したキーと Promise を生成する関数を指定します。
SSR 対応のコレクションクエリSuspense useFindコレクションと find の引数タプルを渡します。
既存のクラスコンポーネントwithTracker対象を絞った保守中はそのまま維持し、フックへの移行は別途計画します。

クラシックなリストのスキャフォールド:

import { useFind, useSubscribe } from "meteor/react-meteor-data";
import { Tasks } from "/imports/api/tasks";

export function TaskList({ listId }) {
  const isLoading = useSubscribe("tasks.byList", listId);
  const tasks = useFind(
    () => Tasks.find({ listId }, { sort: { createdAt: -1 } }),
    [listId],
  );

  if (isLoading()) return <p>Loading...</p>;
  if (tasks.length === 0) return <p>No tasks.</p>;
  return <ul>{tasks.map((task) => <li key={task._id}>{task.title}</li>)}</ul>;
}

useFind はカーソルの監視を担い、変更されたドキュメント参照のみを更新します。変換済みの集計が明確な場合は useTracker を使います。依存関係や skipUpdate を調整する前に、references/react-meteor-data.md を読んでください。

Suspense と非同期リアクティビティ

Suspense のインポートではシグネチャが変わります。ドロップイン置換ではありません。

import { Suspense } from "react";
import { useFind, useSubscribe } from "meteor/react-meteor-data/suspense";
import { Tasks } from "/imports/api/tasks";

function TaskList({ listId }) {
  useSubscribe("tasks.byList", listId);
  const tasks = useFind(Tasks, [
    { listId },
    { sort: { createdAt: -1 } },
  ], [listId]);
  return <ul>{tasks.map((task) => <li key={task._id}>{task.title}</li>)}</ul>;
}

export function TaskScreen({ listId }) {
  return (
    <AppErrorBoundary>
      <Suspense fallback={<p>Loading...</p>}>
        <TaskList listId={listId} />
      </Suspense>
    </AppErrorBoundary>
  );
}

Suspense の useSubscribe は、サスペンド専用の呼び出しとして扱ってください。現在監査済みのパッケージでは、宣言された戻り値の型と実行時の値が一致しないため、戻り値を使用しないでください。安定したキー、拒否、SSR、await 後の Tracker.withComputation については、references/suspense-and-async.md を読んでください。

ビルドと更新の管理

Rspack はアプリの npm 依存関係から React を検出し、JSX または TSX の SWC パーサーを有効にして、クライアント開発用に React Refresh をインストールして注入します。通常の React Rspack アプリでは、更新プラグインを手動で追加する必要はありません。

rspack.config.* は最小限に保ってください。生成される JavaScript のひな形ではオプションの SVGR ルールを示し、TypeScript のひな形では型チェックを示しています。Meteor の SWC デフォルト設定を置き換えずに、@meteorjs/rspack の defineConfig を使ってカスタムルールを組み合わせてください。

React Compiler については、Meteor 3.6-beta.0 の組み合わせでは SWC がサポートされます。それ以前の組み合わせでは Babel を引き続き使用できます。React のバージョンターゲットとランタイム要件については、コンパイラーの設定を参照してください。

リクエスト担当
React の検出、JSX または TSX、React Refresh 境界このスキル
rspack.config の一般的なヘルパー、SWC、エイリアス、キャッシュ、チャンクmeteor-modern-build-stack
既存アプリまたはレガシーのビルドプラグインを Rspack に変換するmigrate-to-rspack
Meteor-bundler の HMR またはカスタムの module.hot ライフサイクルビルドスキル。その後、React の症状についてはこのスキル

編集によってページが再読み込みされたり、コンポーネントの状態がリセットされたりする場合は、まずモジュールをコンパイルしたバンドラーを特定してください。Rspack のクライアントグラフでは、React Refresh の境界を調べ、2 つ目の react-fast-refresh スタックを追加しないでください。Meteor-bundler のグラフでは、hot-module-replacement とバンドル済みの React Fast Refresh 統合を確認してください。references/build-refresh-and-testing.md を参照してください。

ミューテーションとテスト

イベントハンドラーから Meteor.callAsync を呼び出し、React の状態で保留中と拒否をモデル化し、バリデーションと認可はメソッド内に残してください。コンポーネントから機密コレクションに直接書き込まないでください。

テストでは、データを props として受け取るプレゼンテーションコンポーネントと、フックを所有するコンテナーを分離してください。前者はプロジェクト既存の React テストライブラリで単体テストします。後者は、制御可能な Minimongo または実際のパブリケーションを使用して、ブラウザーのクライアントでテストします。React は処理を破棄し、初期レンダリングロジックを複数回呼び出すことがあるため、リアクティブ関数の呼び出し回数ではなく、レンダリングされた動作を検証してください。

アンチパターン

  • 従来の isLoading をブール値として扱うこと。これは関数なので、呼び出す必要があります。
  • Tasks.find().fetch() を useFind に渡すこと。カーソルを返してください。
  • useFind ファクトリー内にサブスクリプションを入れること。サブスクライブは別に行ってください。
  • useTracker のリアクティブ関数内で、React の状態セッター、メソッド、分析処理、または任意の副作用を呼び出すこと。
  • すべての従来型コンポーネントに Suspense を強制すること。どちらの方式も引き続き有用です。
  • 無関係なマウント済み計算に、汎用的な Suspense キーを再利用すること。
  • 計算を復元せず、await の後にのみ Tracker ソースを読み取ること。
  • Meteor がすでに注入している場合に、プロジェクト設定へ @rspack/plugin-react-refresh を追加すること。
  • 1 つの React トランスフォームを追加するために、すべての Rspack SWC オプションを置き換えること。拡張してください。
  • コンポーネントの統合テストですべての Meteor データ動作をモックで取り除くこと。

信頼できるリソース

コメント