composition-patterns について
React コンポーネントをブール型プロパティの増加に頼らず、合成によって柔軟かつ保守しやすく設計するスキルです。共有状態やコンポーネントの関係、描画制御に応じたパターン選択をエージェントに案内します。
主な機能
- 01複合コンポーネントパターン
- 02共有状態のリフトアップ
- 03内部合成
- 04描画の委譲
- 05ブール型プロパティの組み合わせ削減
活用シーン
- 01巨大な React コンポーネントのリファクタリング
- 02コンポーネントライブラリやデザインシステムの構築
- 03タブ、アコーディオン、セレクト間の状態共有
- 04子要素のレイアウトを利用側で制御
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ itallstartedwithaidea/ agent-skills --skill composition-patternsインストール後、Claude Code で/composition-patternsを入力して読み込まれたか確認します。
詳細
コンポジションパターン
googleadsagent.ai™ による Agent Skills™ の一部です
説明
コンポジションパターンでは、複合コンポーネント、状態のリフトアップ、内部コンポジション、ブール型プロパティの増殖の解消を用いて、柔軟で保守しやすい React コンポーネントを構築する方法をエージェントに教えます。これらのパターンは、硬直的でプロパティの多い API を、要件の変化に応じてスムーズに拡張できるコンポーザブルなインターフェースに置き換えます。
React でエージェントが最もよく犯す間違いは、showHeader、showFooter、isCompact、isLoading、hasSearch、enableDarkMode のように、何十個ものブール型プロパティを持つモノリシックなコンポーネントを作ることです。ブール値が1つ増えるたびにコンポーネントの状態空間は倍増し、テスト対象が指数関数的に拡大するうえ、内部構造を変更しなければ拡張できないコンポーネントになってしまいます。コンポジションパターンでは、これらのブール値を構造的なコンポジションに置き換え、利用側が小さなパーツを組み合わせてコンポーネントを構成できるようにします。
このスキルでは、相互に補完する4つのパターンを扱います。関連する UI ファミリー向けの複合コンポーネント、複数のコンポーネントで共有する状態向けの状態のリフトアップ、サブレンダリングをカプセル化する内部コンポジション、そして利用側に最大限の柔軟性をもたらすレンダリングの委譲です。これらのパターンを組み合わせることで、使いやすく、カスタマイズ性に優れ、簡単にテストできるコンポーネントを実現できます。
使用する場面
- コンポーネントに3つを超えるブール型の設定プロパティがある場合
- 関連するコンポーネント間で暗黙的な状態を共有する必要がある場合(タブ、アコーディオン、セレクトなど)
- 利用側でサブ要素のレイアウトや順序を制御する必要がある場合
- 設計時に想定されていなかったユースケースにも対応する必要がある場合
- 「何でもするコンポーネント」をコンポーザブルなパーツにリファクタリングする場合
- コンポーネントライブラリやデザインシステムを構築する場合
仕組み
graph TD
A[Component Design Request] --> B{Pattern Selection}
B --> C[Compound: Related UI Family]
B --> D[State Lifting: Shared State]
B --> E[Internal Composition: Sub-render]
B --> F[Render Delegation: Consumer Control]
C --> G[Parent provides context]
G --> H[Children consume context]
D --> I[State lives in nearest common ancestor]
E --> J[Component composes internally]
F --> K[Consumer passes render function]
エージェントは、コンポーネント間の関係、利用側に必要な制御の度合い、共有状態の複雑さに基づいて、適切なパターンを選択します。
実装
複合コンポーネント
const TabsContext = createContext<TabsState | null>(null);
function Tabs({ defaultValue, children }: TabsProps) {
const [active, setActive] = useState(defaultValue);
return (
<TabsContext.Provider value={{ active, setActive }}>
<div role="tablist">{children}</div>
</TabsContext.Provider>
);
}
function Tab({ value, children }: TabProps) {
const { active, setActive } = useContext(TabsContext)!;
return (
<button
role="tab"
aria-selected={active === value}
onClick={() => setActive(value)}
>
{children}
</button>
);
}
function TabPanel({ value, children }: TabPanelProps) {
const { active } = useContext(TabsContext)!;
if (active !== value) return null;
return <div role="tabpanel">{children}</div>;
}
Tabs.Tab = Tab;
Tabs.Panel = TabPanel;
// Usage: consumer controls structure
<Tabs defaultValue="a">
<Tabs.Tab value="a">Tab A</Tabs.Tab>
<Tabs.Tab value="b">Tab B</Tabs.Tab>
<Tabs.Panel value="a">Content A</Tabs.Panel>
<Tabs.Panel value="b">Content B</Tabs.Panel>
</Tabs>
ブール型プロパティの解消
// BAD: Boolean prop explosion
<Card
showHeader={true}
showFooter={false}
isCompact={true}
hasAvatar={true}
showActions={true}
/>
// GOOD: Compositional API
<Card compact>
<Card.Header>
<Avatar src={user.avatar} />
<Card.Title>{user.name}</Card.Title>
</Card.Header>
<Card.Body>{content}</Card.Body>
<Card.Actions>
<Button>Edit</Button>
<Button>Delete</Button>
</Card.Actions>
</Card>
ベストプラクティス
- サブ要素間で暗黙的な状態を共有する場合は、複合コンポーネントを使用します
- 新機能のためにブール型フラグを追加するのではなく、コンポーザブルな API を公開します
- コンテキストプロバイダーの範囲を絞ります。巨大なコンテキストを1つ作るのではなく、関心事ごとにコンテキストを用意します
- シンプルなユースケースをシンプルなまま保てるよう、適切なデフォルト値を設定します
- プロパティ一覧だけでなく、使用例とともにコンポジション API をドキュメント化します
- ブール型プロパティの組み合わせではなく、TypeScript の判別可能なユニオンを使用します
プラットフォーム互換性
| プラットフォーム | サポート | 備考 |
|---|---|---|
| Cursor | 完全 | コンポーネントの生成とリファクタリング |
| VS Code | 完全 | TypeScript に対応したリファクタリング |
| Windsurf | 完全 | React パターンの認識 |
| Claude Code | 完全 | コンポーネント設計のガイダンス |
| Cline | 完全 | パターンに基づく生成 |
| aider | 部分的 | コンポジションの認識が限定的 |
関連スキル
キーワード
composition compound-components react-patterns state-lifting boolean-props render-delegation design-system composable-api
© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License