This repository contains examples of common React design patterns that help in building maintainable and scalable applications. Each pattern demonstrates a specific approach to solving common React development challenges.
- Compound Components Pattern
- Function as a Child Pattern
- Higher-Order Component (HOC) Pattern
- Proxy Component Pattern
- Render Prop Pattern
- Slot Pattern (Component Injection)
Location: /Compound Components/Accordion.jsx
The Compound Components pattern allows you to create components that work together to form a cohesive unit while maintaining flexibility and control over their rendering. This pattern is particularly useful when you have components that share related state and logic.
Example use case:
<Accordion>
<Accordion.Item>
<Accordion.Header>Section 1</Accordion.Header>
<Accordion.Content>Content for section 1</Accordion.Content>
</Accordion.Item>
</Accordion>Location:
/Function as a Child/Counter.jsx/Function as a Child/Paginator.jsx/Function as a Child/UserFilter.jsx
Also known as Render Props with Functions, this pattern involves passing a function as the child of a component. This pattern provides maximum flexibility for rendering and data handling.
Example use case:
<Counter>
{(count, increment) => (
<button onClick={increment}>
Clicked {count} times
</button>
)}
</Counter>Location: /HOC Pattern/withFetchData.jsx
HOCs are functions that take a component and return a new component with additional props or behavior. This pattern is excellent for reusing component logic across multiple components.
Example use case:
const UserListWithData = withFetchData(UserList, '/api/users');Location:
/Proxy Component/createReactiveState.jsx/Proxy Component/WithPropsProxy.jsx
The Proxy Component pattern involves creating a component that acts as an intermediary, controlling access to another component's props or behavior. This pattern is useful for adding additional functionality or validation to existing components.
Example use case:
const EnhancedButton = WithPropsProxy(Button, {
onClick: (originalOnClick) => (...args) => {
console.log('Button clicked');
originalOnClick(...args);
}
});Location:
/Render Prop/DataFetcher.jsx/Render Prop/ListRenderer.jsx/Render Prop/TableRenderer.jsx
The Render Prop pattern involves passing a prop that tells a component what to render. This pattern provides excellent separation of concerns and reusability.
Example use case:
<DataFetcher
url="/api/data"
render={data => (
<div>
{data.map(item => <Item key={item.id} {...item} />)}
</div>
)}
/>Location: /Slot Pattern (Component Injection)/CardSlot.jsx
The Slot Pattern, also known as Component Injection, allows you to create components with predefined "slots" where other components can be injected. This pattern is great for creating flexible, reusable layouts.
Example use case:
<Card>
<Card.Header>
<h2>Card Title</h2>
</Card.Header>
<Card.Body>
<p>Card content goes here</p>
</Card.Body>
<Card.Footer>
<Button>Action</Button>
</Card.Footer>
</Card>Contributions are welcome! Please feel free to submit a Pull Request.