Components and Props
Core patterns for defining function components, shaping props, and composing UI without prop-drilling pain.
Busque em todas as páginas da documentação
Core patterns for defining function components, shaping props, and composing UI without prop-drilling pain.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
A component is a function that accepts props and returns React nodes. Name it with a capital letter so JSX treats it as a component.
type HelloProps = { name: string };
function Hello({ name }: HelloProps) {
return <p>Hello, {name}</p>;
}Destructure at the parameter list for readability. Keep the full props object only when you need to forward most of it.
function Price({ amount, currency }: { amount: number; currency: string }) {
return <span>{currency} {amount.toFixed(2)}</span>;
}Prefer default parameter values for optional props. They document defaults next to the parameter and type-check cleanly.
function Badge({ label = "New" }: { label?: string }) {
return <span className="badge">{label}</span>;
}children is the content nested between opening and closing tags. Type it as React.ReactNode unless you need a narrower shape.
function Panel({ children }: { children: React.ReactNode }) {
return <section className="panel">{children}</section>;
}Never mutate props or nested prop objects. Treat them as a snapshot from the parent for this render.
// Good: derive a new value
const title = props.title.trim();
// Avoid: props.title = props.title.trim();Parents keep state and pass event callbacks down. Children call the callback with a payload; they do not own the source of truth.
function TodoItem({ id, onRemove }: { id: string; onRemove: (id: string) => void }) {
return (
<button type="button" onClick={() => onRemove(id)}>
Remove
</button>
);
}Pick known props, then spread the remainder onto a host element. Useful for input wrappers and polymorphic building blocks.
type ButtonProps = React.ComponentProps<"button"> & { loading?: boolean };
function Button({ loading, children, ...rest }: ButtonProps) {
return (
<button {...rest} disabled={loading || rest.disabled}>
{children}
</button>
);
}Pass a component type when the child decides structure but the parent picks which widget to render (icon, as-prop patterns).
type RowProps = { icon: React.ComponentType<{ className?: string }> };
function Row({ icon: Icon }: RowProps) {
return <Icon className="row-icon" />;
}A prop or children can be a function of data. Use sparingly when the parent needs full control of the rendered output.
type ListProps<T> = {
items: T[];
children: (item: T) => React.ReactNode;
};
function List<T>({ items, children }: ListProps<T>) {
return <ul>{items.map((item, i) => <li key={i}>{children(item)}</li>)}</ul>;
}Any prop value can be an expression. Build flags and attributes from state without extra intermediate components.
return (
<dialog open={isOpen} aria-labelledby={titleId}>
{body}
</dialog>
);Build layouts by nesting components rather than giant prop lists. Outer shells provide structure; inner pieces provide content.
return (
<AppShell>
<AppShell.Nav />
<AppShell.Main>{page}</AppShell.Main>
</AppShell>
);When a return grows large, extract named components in the same file. Keep props explicit so data flow stays obvious.
function UserCard({ user }: { user: User }) {
return (
<article>
<UserHeader user={user} />
<UserStats stats={user.stats} />
</article>
);
}Set displayName on HOCs or memo wrappers so React DevTools shows a useful name.
const MemoRow = React.memo(Row);
MemoRow.displayName = "MemoRow";Model nested object props with interfaces or type aliases. Prefer required fields and mark only true optionals with ?.
type Address = { line1: string; city: string; zip: string };
type ProfileProps = { name: string; address: Address };cloneElement couples parent and child. Prefer explicit props, composition, or context instead of injecting props into opaque children.
// Prefer: <Tabs><Tabs.List /><Tabs.Panel /></Tabs>
// Avoid: React.Children.map(children, (child) => cloneElement(child, extra))Stack versions: React 19 · TypeScript (strict) · modern JSX transform
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥