---
name: react-component-architecture
description: Modern React component patterns with hooks, composition, and TypeScript
license: MIT
compatibility: react 18+, typescript 5+
allowed-tools: read_file write_file apply_patch search_with_context
---
# React Component Architecture
## Component Design Principles
1. **Single Responsibility** - Each component does one thing well
2. **Composition Over Configuration** - Use children and render props over prop drilling
3. **Colocation** - Keep related code together (styles, tests, types)
4. **Controlled vs Uncontrolled** - Be explicit about state ownership
## Component Patterns
### Compound Components
For complex UI with shared state:
```typescript
const Tabs = ({ children, defaultValue }: TabsProps) => {
const [active, setActive] = useState(defaultValue);
return (
{children}
);
};
Tabs.List = TabsList;
Tabs.Trigger = TabsTrigger;
Tabs.Content = TabsContent;
```
### Render Props for Flexibility
When consumers need control over rendering:
```typescript
interface ListProps {
items: T[];
renderItem: (item: T, index: number) => ReactNode;
keyExtractor: (item: T) => string;
}
function List({ items, renderItem, keyExtractor }: ListProps) {
return items.map((item, i) => (
{renderItem(item, i)}
));
}
```
### Custom Hooks for Logic Extraction
Extract reusable stateful logic:
```typescript
function useToggle(initial = false) {
const [state, setState] = useState(initial);
const toggle = useCallback(() => setState(s => !s), []);
const setTrue = useCallback(() => setState(true), []);
const setFalse = useCallback(() => setState(false), []);
return { state, toggle, setTrue, setFalse } as const;
}
```
### Polymorphic Components
Components that render as different elements:
```typescript
type PolymorphicProps = {
as?: E;
} & ComponentPropsWithoutRef;
function Box({
as,
...props
}: PolymorphicProps) {
const Component = as || 'div';
return ;
}
```
## Props Patterns
### Discriminated Union Props
For mutually exclusive prop combinations:
```typescript
type ButtonProps =
| { variant: 'link'; href: string; onClick?: never }
| { variant: 'button'; onClick: () => void; href?: never };
```
### Default Props with Destructuring
```typescript
function Button({
variant = 'primary',
size = 'md',
...props
}: ButtonProps) {
// ...
}
```
## Performance Patterns
1. **Memoize expensive computations** with `useMemo`
2. **Memoize callbacks** passed to children with `useCallback`
3. **Split contexts** by update frequency
4. **Use `React.memo`** for pure presentational components
5. **Virtualize long lists** with react-virtual or similar
## File Structure
```
components/
Button/
Button.tsx # Component
Button.test.tsx # Tests
Button.types.ts # Types (if complex)
index.ts # Re-export
```