SOLID React
SOLID translated into React habits — separate data from rendering, extend through composition, keep props minimal and depend on abstractions you pass in.
On this page
SOLID was written with classes in mind, and React mostly avoids classes. But the principles translate surprisingly well once you stop reading them literally. Here’s how I apply each one — only where it pays for itself.
Single responsibility
A component should have one reason to change. In practice that means separating data and logic from rendering: a custom hook fetches and shapes the data; the component just renders props. No more mega-components.
const useWorkout = (id: string) =>
useQuery({ queryKey: ["workout", id], queryFn: () => api.getWorkout(id) });
const WorkoutCard = ({ id }: { id: string }) => {
const { data } = useWorkout(id);
return <Card title={data?.name} />;
};
Open/closed
Extend behaviour without editing the component. In React that means composition — children, slots, render props — rather than inheritance or yet another boolean prop.
<Card header={<Badge>PR</Badge>} footer={<ShareButton />} />
The “boolean prop explosion” (<Button primary large danger outline>) is the classic open/closed smell. Use variants or
composition instead.
Liskov substitution
A specialised component should honour the contract of the one it extends: same props, same behaviour, plus extras. An
IconButton that silently ignores disabled breaks every caller that relied on Button.
Interface segregation
Pass what’s needed, not the whole object. <Avatar name={user.name} src={user.avatarUrl} /> beats
<Avatar user={user} />. The component is easier to reuse, to test and to reason about, and it won’t re-render because some
unrelated field on user changed.
Dependency inversion
Depend on abstractions you’re given rather than reaching out for concrete ones. Inject the API client through context or props, and tests can pass in a fake. This is the same idea as an anti-corruption layer at the data boundary — see API Modelling.
Where I stop
SOLID applied zealously produces a forest of tiny files and indirection nobody can follow. My rule: apply a principle when it removes a real pain — a component that’s hard to test, a change that touched ten files — not pre-emptively. These habits sit naturally inside the feature-based structure of Bulletproof React.
- #react
- #solid
- #design-principles
- #composition
↩ Linked from (3)
- API ModellingEvergreen
This is the adapter pattern, sometimes called an anti-corruption layer, plus the dependency inversion from SOLID React: components depend on your model, not on someone else's API.
- Bulletproof ReactGrowing
…hemselves, the proposal for the team was concrete, with a working example instead of a slide. Related habits: SOLID React and API Modelling.
Shift Left Testing · Building a Low-Code BPMN Workflow Platform · SOLID React
↪ Links to (2)
Related by topic
- Growingcase study
A Testing Strategy Teams Actually Adopted
Frontend craft - Growingcase study
Building a Graph Component Library
Frontend craft - Growingcase study
Building a Low-Code BPMN Workflow Platform
Frontend craft - Growingcase study
Chairing a Cross-Team UI Guild
Career