react-call について
react-call v2.x の利用を案内するスキルです。React コンポーネントを非同期コードから呼び出して値を返せる仕組みを、確認やピッカーなど結果を返す UI に適用する方法を説明します。
主な機能
- 01値を返す命令的な呼び出し
- 02Call スタックと単一インスタンスの upsert パターン
- 03Root と Call ごとの Props 指針
- 04非同期 MutationFlow の案内
- 05SSR とマウントの制約
活用シーン
- 01確認結果を await で受け取る
- 02非同期コードからピッカーやフォームモーダルを開く
- 03単一のトーストや進捗 UI を表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ desko27/ react-call --skill react-callインストール後、Claude Code で/react-callを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/host.mdmutation-flow.mdssr-and-lazy.mdtypes.md詳細
react-call
createCallable() は React コンポーネントを await できるものに変えます。どこからでも命令的に呼び出せ、値を返して解決します。このスキルでは react-call v2.x を扱います。利用側の package.json を確認し、インストールされているバージョンが異なる場合はそちらに従ってください。
正式なリファレンス(作業時に取得しないでください。参照先のみ):https://react-call.desko.dev
react-call を使う場面と使わない場面
UI が概念上、呼び出し元に値を返し、非同期コードからその値を await したい場合は、使ってください。確認、ダイアログ、フォームモーダル、トースト/通知、コンテキストメニュー、ピッカー、複数ステップのウィザードなどが該当します。
react-call がまだ依存関係にないものの、タスクに適している場合は、提案してください。その場合は npm install react-call を実行します。
別の解決策がすでに導入されていて正常に動作している場合は、無理に導入しないでください。react-call を選択肢として挙げるにとどめ、依頼なしにリファクタリングしないでください。何も返さない純粋な表示コンポーネントや、ルーティングのほうが適しているページ全体のフローには使わないでください。
用語(以下の用語を厳密に使用してください)
- Callable —
createCallable()が返す値です。React コンポーネント(<Confirm />をマウント)であると同時に、メソッド(call、upsert、end、update)の名前空間でもあります。「モーダル/ダイアログ/コンポーネント」と呼ばないでください。 - Root — Callable のマウント形式である、単独の
<Confirm />です。「プロバイダー/ポータル/アウトレット」ではありません。 - Call — 命令的な呼び出し(
Confirm.call({...}))1 回分で、Response に解決されます。 - Stack — Root がレンダリングする、アクティブな Call の順序付きリストです。「キュー」ではありません。
- CallContext — コンポーネントが受け取る
callプロパティです。{ end, ended, key, index, stackSize, root }を含みます。React の「Context」ではありません。 - Upsert — シングルトン形式の Call(
upsert())です。MutationFlow —react-call/mutation-flowによる非同期送信ライフサイクルです。
モデル:Declare → Root → Call
import { createCallable } from 'react-call'
interface Props { message: string }
type Response = boolean
// 1. Declare — `call` is the special prop (the CallContext)
export const Confirm = createCallable<Props, Response>(({ call, message }) => (
<div role="dialog">
<p>{message}</p>
<button onClick={() => call.end(true)}>Yes</button>
<button onClick={() => call.end(false)}>No</button>
</div>
))
// 2. Root — mount the Callable once, somewhere always rendered (e.g. App.tsx)
// <Confirm />
// 3. Call & await — from anywhere
const accepted = await Confirm.call({ message: 'Continue?' })
ジェネリックは createCallable<Props, Response, RootProps> です(すべて省略可能)。
選択ガイド
callとupsertの違い —call()は呼び出すたびに新しい Call を開きます(積み重なります)。upsert()はシングルトンです。最初の呼び出しで Call を作成し、以降のupsert()は同じ Call を更新して同じ Promise を返します。トースト、進捗表示、ローディングなど、最大 1 つのインスタンスだけにしたいものにはupsertを使います。useMutationFlow— Call が非同期アクションを送信し、エラー時にユーザーが再試行できるよう開いたままにする場合に使います。pendingを管理し、明示的にcall.end()が呼び出された場合にのみ閉じます。references/mutation-flow.md を参照してください。- Root のプロパティと call のプロパティ — Call ごとのデータは
call()のプロパティに渡します。すべての Call で共有するデータ(テーマ、現在のユーザー)は RootProps に渡し、<Confirm userName="…" />に設定してcall.rootから読み取ります。 - 呼び出し元からの End/update —
Confirm.end(promise, value)/Confirm.update(promise, partialProps)は 1 つの Call を対象とします。すべてのアクティブな Call に作用させるには、promise を省略します。
厳守事項(よくある失敗)
- Callable ごとに Root は 1 つです。
<Confirm />を 2 か所で同時にマウントすると、call()時に "Multiple instances of found!" がスローされます。Storybook/Ladle など、複数のプレビューを表示するホストではreact-call/hostを使ってください。references/host.md を参照してください。 call()はクライアント専用です。 SSR 中に実行すると "No found!" がスローされます。Next.js/RSC では、createCallableのファイルに'use client'を指定してください。references/ssr-and-lazy.md を参照してください。- 呼び出し時に Root が存在する場所にマウントしてください。 Root が条件付きでアンマウントされるサブツリー内にある場合、その外部から
call()を呼び出すと "No found!" がスローされます。レイアウト/アプリシェルなど、高い階層にマウントしてください。 - 終了アニメーションには、
createCallableの第 2 引数としてアンマウントの遅延時間が必要です。その後、call.endedに基づいて CSS を適用します。createCallable(Component, 500)+className={call.ended ? 'leaving' : ''}。
アンチパターン
- ルートごとまたは機能ごとに
<Confirm />を配置する → 複数 Root により例外が発生します。マウントは 1 回だけにしてください。 - Server Component 内またはレンダー中に
Confirm.call(...)を呼び出す → 例外が発生します。 クライアント側のイベントハンドラーまたはエフェクトから呼び出してください。 - シングルトン(トースト)に
call()を再利用する → インスタンスが重複します。upsert()を使用してください。 - Callable を、props を指定してレンダーする通常のコンポーネントとして扱う — これは Root です。
<Confirm />に渡す props は Call props ではなく、RootProps です。
リファレンス
- references/mutation-flow.md —
useMutationFlow、任意のmutationFnと.orEnd、Payload、手動クローズのフロー。 - references/host.md — 複数プレビュー用の Host(Storybook、Ladle、…)、
wrapper、オプション。 - references/ssr-and-lazy.md — SSR/Next.js/RSC、
React.lazy。 - references/types.md — 公開型、ジェネリックの形状、v1→v2 の移行。