02-component-composition
React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives
- License 许可
- MIT
- 最近更新
- 2026-05-31
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- 02-component-composition
- license
- MIT
- description
- React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives
- compatibility
- opencode
03 SKILL.md 正文
React Component Composition
List Rendering — Always Use map
NEVER render lists statically. Use Array.map with proper keys.
// ❌ STATIC — hard to maintain, violates DRY
<div>
<Item name="Alice" />
<Item name="Bob" />
<Item name="Carol" />
</div>
// ✅ DYNAMIC — data-driven, composable
<div>
{users.map((user) => (
<Item key={user.id} name={user.name} />
))}
</div>
Key Rules
- Use stable IDs — never array index as key
- Key at the top level — on the mapped component, not nested
- Fragment with key — when mapping to multiple elements
// ❌ index as key — causes reordering bugs
{
items.map((item, i) => <Item key={i} {...item} />);
}
// ✅ stable id
{
items.map((item) => <Item key={item.id} {...item} />);
}
// ✅ fragment with key when multiple children
{
items.map((item) => (
<React.Fragment key={item.id}>
<dt>{item.name}</dt>
<dd>{item.value}</dd>
</React.Fragment>
));
}
Conditional Rendering — Pattern Match
// ✅ early return for guard clauses
if (!data) return <Loading />;
if (error) return <Error error={error} />;
// ✅ ternary for binary choice
return isEditing ? <EditForm /> : <DisplayView />;
// ✅ logical AND for simple toggle
return showBanner && <Banner />;
// ✅ record lookup for multiple variants
const variants = {
idle: <Idle />,
loading: <Loading />,
success: <Success data={data} />,
error: <Error error={error} />,
};
return variants[status];
Compound Components
Group related components that share state implicitly.
// Tabs compound component
<Tabs value={activeTab} onValueChange={setActiveTab}>
<Tabs.List>
<Tabs.Trigger value="overview">Overview</Tabs.Trigger>
<Tabs.Trigger value="details">Details</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="overview">
<Overview />
</Tabs.Content>
<Tabs.Content value="details">
<Details />
</Tabs.Content>
</Tabs>
Render Props / Slots
Allow parent to inject content without prop drilling.
// Slot pattern
<Card>
<Card.Header>
<h2>Title</h2>
</Card.Header>
<Card.Body>
<p>Content goes here</p>
</Card.Body>
<Card.Footer>
<Button>Action</Button>
</Card.Footer>
</Card>
// Render prop for customization
<DataTable
data={rows}
renderRow={(row) => (
<CustomRow data={row} onSelect={handleSelect} />
)}
/>
Layout Primitives
Create reusable layout components instead of repeating flex/grid classes.
// Stack — vertical spacing
<Stack gap={4}>
<Item />
<Item />
<Item />
</Stack>
// Grid — responsive columns
<Grid columns={{ mobile: 1, tablet: 2, desktop: 3 }} gap={4}>
{items.map((item) => <Card key={item.id} {...item} />)}
</Grid>
// Cluster — horizontal wrapping
<Cluster gap={2}>
{tags.map((tag) => <Badge key={tag}>{tag}</Badge>)}
</Cluster>
Component Boundaries
Split components at data boundaries:
// ❌ one giant component
function Page() {
const [data, setData] = useState();
const [filter, setFilter] = useState();
// ... 200 lines of mixed concerns
}
// ✅ separated by concern
function Page() {
return (
<PageLayout>
<FilterBar />
<DataList />
</PageLayout>
);
}
function DataList() {
const data = useData(); // custom hook
return (
<Stack>
{data.map((item) => (
<DataCard key={item.id} {...item} />
))}
</Stack>
);
}
04 同仓库更多 Skills
tmux-workflow
Development workflow with tmux — run dev servers, Storybook, and background processes in persistent sessions with live logs, while keeping OpenCode free for chat
04-anti-patterns
React anti-patterns to avoid — manual JSX repetition, useEffect misuse, reference instability, prop drilling, conditional hooks, and common performance traps
03-state-management
React state management patterns — lifting state, colocation, URL state, server state with TanStack Query, local state with useState/useReducer
02-component-composition
React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives
01-fp-style
React functional programming style — pure components, hooks conventions, Effect Atom integration, and Tailwind patterns
react-animation
React animation with react/motion (Framer Motion) — declarative animations, gestures, layout animations, and performance best practices