React Patterns
Practical React patterns we use at Enddesk for building maintainable, performant applications.
Component Composition
Prefer composition over configuration. Instead of a single component with many props, compose smaller components:
// Prefer this:
<Card>
<Card.Header>
<Card.Title>Dashboard</Card.Title>
</Card.Header>
<Card.Body>
<MetricsGrid />
</Card.Body>
</Card>
// Over this:
<Card
title="Dashboard"
headerVariant="large"
showBorder
bodyPadding="lg"
>
<MetricsGrid />
</Card>
Custom Hooks for Logic Reuse
Extract business logic into custom hooks to keep components focused on rendering:
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
Error Boundaries
Always wrap feature sections in error boundaries to prevent cascading failures:
<ErrorBoundary fallback={<ErrorCard />}>
<DashboardWidget />
</ErrorBoundary>
Key Takeaways
- Compose small, focused components
- Extract logic into custom hooks
- Use error boundaries at feature boundaries
- Keep components pure when possible