用 composition-patterns 让 AI 写出可维护的 React 组合代码

前言

在 React 项目里,组件一复杂就容易长出一堆布尔参数:isThreadisEditingisDMThreadshowAttachments……每多一个开关,可能状态就翻一倍,条件分支也跟着膨胀。人写的时候已经难维护,让 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.mdAGENTS.mdskills.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):不要用 isThreadisEditing 这类开关定制行为,每个布尔都会倍增可能状态。正确做法是拆成明确变体,例如 ChannelComposerThreadComposerEditComposer,各自组合需要的子件。

使用复合组件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。
  • 把状态抬到 Providerstate-lift-state):状态不困在视觉组件内部,同级甚至「框外」的按钮、预览也能读写,而不用 props 穿透或别扭的 ref。

3. 实现模式(MEDIUM)

  • 显式变体patterns-explicit-variants):做 ThreadComposerEditComposer,而不是一个 Composer 加一堆模式布尔。
  • 优先 children,少用 render propspatterns-children-over-render-props):用组合拼 UI,而不是 renderHeaderrenderFooter 一类回调 props。

4. React 19 API(MEDIUM)

仅适用于 React 19+。官方明确:不要再写 forwardRefref 可作为普通 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

注意:

  1. 这是架构/组合模式 Skill,不是性能专项(性能可看同仓库的 react-best-practices)。官方材料也未把「服务端/客户端边界」作为本 Skill 主题。
  2. React 19 一节有版本门槛;React 18 项目应忽略 react19-* 规则。
  3. 规则里大量示例偏向复合组件与 Context;若组件本身极简单,不必为了「套模式」硬拆。
  4. 以仓库内 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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜