Files
HausApp/.agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md
René Schober 4e34270786 initial commit
2026-03-13 06:23:06 +01:00

85 lines
1.8 KiB
Markdown

---
title: Prefer Composing Children Over Render Props
impact: MEDIUM
impactDescription: cleaner composition, better readability
tags: composition, children, render-props
---
## Prefer Children Over Render Props
Use `children` for composition instead of `renderX` props. Children are more
readable, compose naturally, and don't require understanding callback
signatures.
**Incorrect (render props):**
```tsx
function Composer({
renderHeader,
renderFooter,
renderActions,
}: {
renderHeader?: () => React.ReactNode;
renderFooter?: () => React.ReactNode;
renderActions?: () => React.ReactNode;
}) {
return (
<form>
{renderHeader?.()}
<Input />
{renderFooter ? renderFooter() : <DefaultFooter />}
{renderActions?.()}
</form>
);
}
// Usage is awkward and inflexible
return (
<Composer
renderHeader={() => <CustomHeader />}
renderFooter={() => (
<>
<Formatting />
<Emojis />
</>
)}
renderActions={() => <SubmitButton />}
/>
);
```
**Correct (compound components with children):**
```tsx
function ComposerFrame({ children }: { children: React.ReactNode }) {
return <form>{children}</form>;
}
function ComposerFooter({ children }: { children: React.ReactNode }) {
return <footer className="flex">{children}</footer>;
}
// Usage is flexible
return (
<Composer.Frame>
<CustomHeader />
<Composer.Input />
<Composer.Footer>
<Composer.Formatting />
<Composer.Emojis />
<SubmitButton />
</Composer.Footer>
</Composer.Frame>
);
```
**When render props are appropriate:**
```tsx
// Render props work well when you need to pass data back
<List data={items} renderItem={({ item, index }) => <Item item={item} index={index} />} />
```
Use render props when the parent needs to provide data or state to the child.
Use children when composing static structure.