用 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
羽毛球分组比赛记分
小程序二维码

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

小夜