前言¶
在 React 项目里,组件一复杂就容易长出一堆布尔参数:isThread、isEditing、isDMThread、showAttachments……每多一个开关,可能状态就翻一倍,条件分支也跟着膨胀。人写的时候已经难维护,让 AI 编程助手在这种组件上继续改,更容易把逻辑越改越乱。
Vercel 在 vercel-labs/agent-skills 仓库里提供了一套名为 composition-patterns 的 Agent Skill(SKILL.md 中声明名为 vercel-composition-patterns,版本 1.0.0,MIT 许可)。它不教零散语法,而是把「组合优于配置」的架构规则写成 Agent 可执行的指导:避免布尔 props 扩散、用复合组件、把状态抬到 Provider、用 children 组合而不是一堆 renderX。本文按官方 SKILL.md、AGENTS.md 与 skills.sh 的说明,介绍它是什么、怎么装、怎么用。
这是什么¶
composition-patterns 是面向 AI 编程 Agent 的 React 组合模式指南。官方摘要写得很清楚:用复合组件、提升状态、组合内部实现,避免布尔 props 扩散,让代码库在规模变大后对人和 AI 都更好改。
它收录在 vercel-labs/agent-skills 中,作者归属为 Vercel(metadata.author: vercel)。文档面向维护、生成、重构 React 代码库的 Agent/LLM,人也可读,但优化目标是自动化与一致性。完整规则汇编在 AGENTS.md,单条规则放在 rules/ 目录,按优先级分成四类。
适合在这些场景启用:
- 重构带大量布尔 props 的组件
- 做可复用组件库
- 设计灵活的组件 API
- Review 组件架构
- 处理复合组件或 Context Provider
核心功能与亮点¶
官方按优先级给出四类规则(与 SKILL.md / AGENTS.md 一致):
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | Component Architecture | HIGH | architecture- |
| 2 | State Management | MEDIUM | state- |
| 3 | Implementation Patterns | MEDIUM | patterns- |
| 4 | React 19 APIs | MEDIUM | react19- |
1. 组件架构(HIGH)¶
避免布尔 props 扩散(architecture-avoid-boolean-props,影响标为 CRITICAL):不要用 isThread、isEditing 这类开关定制行为,每个布尔都会倍增可能状态。正确做法是拆成明确变体,例如 ChannelComposer、ThreadComposer、EditComposer,各自组合需要的子件。
使用复合组件(architecture-compound-components):复杂组件用共享 Context 的复合结构,子组件从 Context 取状态,而不是层层 props。导出形如 Composer.Provider / Composer.Frame / Composer.Input,由调用方按需拼装。
2. 状态管理(MEDIUM)¶
- 状态与 UI 解耦(
state-decouple-implementation):只有 Provider 知道状态来自useState、Zustand 还是服务端同步;UI 只消费 Context 接口。 - 通用 Context 接口(
state-context-interface):约定state/actions/meta三部分,便于依赖注入;同一套 UI 可挂不同 Provider。 - 把状态抬到 Provider(
state-lift-state):状态不困在视觉组件内部,同级甚至「框外」的按钮、预览也能读写,而不用 props 穿透或别扭的 ref。
3. 实现模式(MEDIUM)¶
- 显式变体(
patterns-explicit-variants):做ThreadComposer、EditComposer,而不是一个Composer加一堆模式布尔。 - 优先 children,少用 render props(
patterns-children-over-render-props):用组合拼 UI,而不是renderHeader、renderFooter一类回调 props。
4. React 19 API(MEDIUM)¶
仅适用于 React 19+。官方明确:不要再写 forwardRef,ref 可作为普通 prop;优先用 use() 替代 useContext()(use() 还可以条件调用)。仍在 React 18 的项目应跳过这一节。
核心原则可以概括成四句(来自该 Skill 的 README):组合优于配置;把状态抬起来;内部子件读 Context;变体要显式命名。
安装与启用¶
该 Skill 遵循 Agent Skills 格式,可通过 Vercel 的 skills CLI 安装。CLI 声明支持 Cursor、Claude Code、Codex、OpenCode 等一批 Agent。
只装 composition-patterns(与 skills.sh 页面一致):
npx skills add https://github.com/vercel-labs/agent-skills --skill composition-patterns
或使用仓库简写,再指定 skill:
npx skills add vercel-labs/agent-skills --skill composition-patterns
安装整个 agent-skills 集合:
npx skills add vercel-labs/agent-skills
常用选项(来自 vercel-labs/skills CLI 文档):
- 默认装到项目下的 Agent skills 目录,便于团队共享
-g:装到用户全局目录-a claude-code/-a cursor等:指定目标 Agent-y:跳过确认,适合 CI
装好后,Agent 在识别到相关任务时会自动引用;也可在对话里明确要求「按 composition-patterns 重构这个组件」。
目录结构大致如下:
SKILL.md:给 Agent 的总说明与规则索引rules/*.md:单条规则(含错误/正确示例)AGENTS.md:全部规则的汇编文档metadata.json:版本与摘要(当前为 1.0.0,日期 January 2026)
典型用法示例¶
1. 让 Agent 按规则重构¶
安装后,可以这样提示(内容对齐官方「何时应用」):
请按 composition-patterns 重构这个 Composer:去掉 isThread / isEditing 等布尔 props,
改成复合组件 + 显式变体(ChannelComposer / ThreadComposer / EditComposer)。
Agent 应按规则读 rules/architecture-avoid-boolean-props.md 等文件,而不是凭印象改。
2. 布尔 props → 组合变体(官方示例精简)¶
错误方向:一个巨型 Composer 靠布尔分支:
function Composer({
onSubmit,
isThread,
channelId,
isDMThread,
dmId,
isEditing,
isForwarding,
}: Props) {
return (
<form>
<Header />
<Input />
{isDMThread ? (
<AlsoSendToDMField id={dmId} />
) : isThread ? (
<AlsoSendToChannelField id={channelId} />
) : null}
{isEditing ? <EditActions /> : isForwarding ? <ForwardActions /> : <DefaultActions />}
<Footer onSubmit={onSubmit} />
</form>
)
}
正确方向:变体各自组合,共享内部件:
function ThreadComposer({ channelId }: { channelId: string }) {
return (
<Composer.Frame>
<Composer.Header />
<Composer.Input />
<AlsoSendToChannelField id={channelId} />
<Composer.Footer>
<Composer.Formatting />
<Composer.Emojis />
<Composer.Submit />
</Composer.Footer>
</Composer.Frame>
)
}
3. 复合组件 + Context 接口¶
官方推荐导出复合对象,并由 Provider 注入 state / actions / meta:
const Composer = {
Provider: ComposerProvider,
Frame: ComposerFrame,
Input: ComposerInput,
Submit: ComposerSubmit,
Header: ComposerHeader,
Footer: ComposerFooter,
}
// 使用
<Composer.Provider state={state} actions={actions} meta={meta}>
<Composer.Frame>
<Composer.Header />
<Composer.Input />
<Composer.Footer>
<Composer.Formatting />
<Composer.Submit />
</Composer.Footer>
</Composer.Frame>
</Composer.Provider>
同一套 Composer.Input 可以挂在本地表单 Provider,也可以挂在频道同步 Provider,因为 UI 只依赖接口,不依赖具体状态实现。
4. React 19 写法(仅 19+)¶
// ref 作为普通 prop,不再包 forwardRef
function ComposerInput({ ref, ...props }: Props & { ref?: React.Ref<TextInput> }) {
return <TextInput ref={ref} {...props} />
}
// 用 use() 读 Context
const value = use(MyContext)
需要单条细则时,可直接打开对应规则文件,例如:
rules/architecture-avoid-boolean-props.md
rules/state-context-interface.md
rules/react19-no-forwardref.md
适用场景与注意事项¶
适合:
- React 组件库、设计系统、聊天/编辑器类复杂表单 UI
- 团队用 Cursor、Claude Code、Codex 等 Agent 做重构或 Code Review
- 希望 AI 生成代码时遵守统一架构,而不是堆 props
注意:
- 这是架构/组合模式 Skill,不是性能专项(性能可看同仓库的
react-best-practices)。官方材料也未把「服务端/客户端边界」作为本 Skill 主题。 - React 19 一节有版本门槛;React 18 项目应忽略
react19-*规则。 - 规则里大量示例偏向复合组件与 Context;若组件本身极简单,不必为了「套模式」硬拆。
- 以仓库内
SKILL.md/rules//AGENTS.md为准;Agent 应读规则文件再改代码,避免只凭摘要发挥。
小结¶
composition-patterns 把「别再加布尔开关、用组合表达变体、状态进 Provider、UI 只认接口」写成了 Agent 可执行的规则集。对人和 AI 来说,价值都在于:组件长大之后,行为仍然可预期、可复用、可替换实现。
官方地址:
- GitHub:https://github.com/vercel-labs/agent-skills/tree/main/skills/composition-patterns
- skills.sh:https://skills.sh/vercel-labs/agent-skills/composition-patterns