关于 react-call
这是 react-call v2.x 的使用指南,可让 React 组件从异步代码中被调用并返回结果。它帮助 React 开发者将此模式用于确认框、选择器等需要向调用方返回值的界面。
主要功能
- 01命令式调用并解析为结果
- 02调用堆栈与单例 upsert 模式
- 03Root 与单次调用属性指引
- 04异步 MutationFlow 指引
- 05SSR 与挂载约束
适用场景
- 01等待确认操作的结果
- 02从异步代码打开选择器或表单模态框
- 03显示单例 Toast 或进度界面
安装
复制下面的命令,在终端中运行。
$
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 该值时:确认框、对话框、表单模态框、Toast/通知、上下文菜单、选择器、多步骤向导。
可以建议使用:如果 react-call 尚未成为依赖项,但任务适合使用它 — 那么运行 npm install react-call。
不要强行推广:如果已有其他方案且运行良好 — 可以提及 react-call 是一种选择,但不要在未被要求时重构。对于不返回任何内容的纯展示型组件,以及更适合通过路由实现的整页流程,请勿使用。
术语(请使用这些准确术语)
- Callable —
createCallable()返回的值。它既是一个 React 组件(挂载<Confirm />),也是一个方法命名空间(call、upsert、end、update)。不要称它为“模态框/对话框/组件”。 - Root — Callable 的挂载形式:裸的
<Confirm />。不要称为“provider/portal/outlet”。 - Call — 一次命令式调用(
Confirm.call({...})),解析为一个 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。Toast、进度提示、加载状态 — 任何最多只应有一个实例的内容,都适合使用upsert。useMutationFlow— 当 Call 提交异步操作且发生错误时应保持打开状态,以便用户重试,就适合使用它。它会管理pending,并且只会在显式调用call.end()时关闭。参见 references/mutation-flow.md。- Root props 与 Call props — 每个 Call 独有的数据放入
call()的 props;所有 Call 共享的数据(主题、当前用户)放入 RootProps,传递给<Confirm userName="…" />并通过call.root读取。 - 从调用方结束/更新 —
Confirm.end(promise, value)/Confirm.update(promise, partialProps)针对一个 Call;省略 promise 则会影响所有活动 Call。
硬性规则(常见故障)
- 每个 Callable 只能有一个 Root。 在两个仍处于活动状态的位置挂载
<Confirm />,会在调用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 错误。只挂载一次。 - 在服务端组件中或渲染期间调用
Confirm.call(...)→ 会抛出错误。 请在客户端的事件处理程序或副作用中调用。 - 对单例(如 toast)重复使用
call()→ 会创建重复实例。请使用upsert()。 - 将 Callable 当作普通组件并传入 props 来渲染——它就是 Root;传给
<Confirm />的 props 是 RootProps,而不是 Call props。
参考
- 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 迁移。
评论
支持 Markdown