# Component Design Patterns
## Rule
All React components MUST be function components with TypeScript interfaces for props. Use composition over inheritance. One component per file. Export named components, not default exports.
## Format
```tsx
interface ComponentNameProps {
requiredProp: string;
optionalProp?: number;
children?: React.ReactNode;
}
export function ComponentName({ requiredProp, optionalProp = 10, children }: ComponentNameProps) {
return <div>{children}</div>;
}
```
## Good Examples
```tsx
// UserCard.tsx — single component, named export, typed props
interface UserCardProps {
user: User;
onEdit?: (userId: string) => void;
variant?: "compact" | "detailed";
className?: string;
}
export function UserCard({
user,
onEdit,
variant = "compact",
className = "",
}: UserCardProps) {
return (
<article className={`user-card user-card--${variant} ${className}`}>
<h3>{user.name}</h3>
<p>{user.email}</p>
{onEdit && (
<button onClick={() => onEdit(user.id)}>Edit</button>
)}
</article>
);
}
// Composition pattern
export function UserList({ users }: { users: User[] }) {
return (
<div className="user-list">
{users.map((user) => (
<UserCard key={user.id} user={user} />
))}
</div>
);
}
```
## Bad Examples
```tsx
// BAD: Class component
class UserCard extends React.Component<Props> {
render() { return <div />; }
}
// BAD: Default export
export default function UserCard() { ... }
// BAD: Untyped props
export function UserCard(props: any) { ... }
// BAD: Multiple components in one file
export function UserCard() { ... }
export function UserAvatar() { ... }
export function UserBadge() { ... }
```
## Enforcement
- ESLint: react/function-component-definition
- ESLint: no-default-export (prefer named)
- One component per file, filename matches component name