React isn’t just about writing components—it’s about writing them in scalable, reusable, and maintainable ways. That’s where design patterns come in. Let’s explore the most important React patterns, with examples, real-world use cases, and why they matter. 🌟
1️⃣ Container & Presentational Pattern 🧑💻🎨
- Container Components: Handle data fetching, state, business logic.
- Presentational Components: Handle UI rendering only.
👉 Use Case: Keeps code clean by separating logic from UI.
// Presentational
const UserList = ({ users }) => (
<ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
);
// Container
const UserListContainer = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("/api/users").then(res => res.json()).then(setUsers);
}, []);
return <UserList users={users} />;
};
✅ Real-world: A UserProfile
component only displays data, while UserProfileContainer
fetches from an API.
2️⃣ Higher-Order Components (HOC) 🔁
A function that takes a component and returns a new component with extended functionality.
👉 Use Case: Code reuse (e.g., authentication, logging, theming).
const withLogger = (Wrapped) => (props) => {
useEffect(() => console.log("Mounted:", Wrapped.name), []);
return <Wrapped {...props} />;
};
const Profile = () => <h2>My Profile</h2>;
export default withLogger(Profile);
✅ Real-world: withAuth
HOC to protect routes.
3️⃣ Render Props 🎭
A pattern where a component’s child is a function that receives state/logic.
👉 Use Case: Share behavior without inheritance or HOCs.
const MouseTracker = ({ children }) => {
const [pos, setPos] = useState({ x: 0, y: 0 });
return (
<div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
{children(pos)}
</div>
);
};
<MouseTracker>
{({ x, y }) => <h1>🐭 Mouse: {x}, {y}</h1>}
</MouseTracker>
✅ Real-world: Tooltips, drag-and-drop, analytics tracking.
4️⃣ Custom Hooks 🪝
Encapsulate logic in reusable hooks.
👉 Use Case: Extract stateful logic from components for reusability.
const useFetch = (url) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url).then(r => r.json()).then(setData);
}, [url]);
return data;
};
const Posts = () => {
const posts = useFetch("/api/posts");
return posts ? posts.map(p => <p key={p.id}>{p.title}</p>) : "⏳ Loading...";
};
✅ Real-world: useAuth
, useLocalStorage
, useDebounce
.
5️⃣ Compound Components 🧩
A set of components working together to provide a flexible API.
👉 Use Case: Flexible UI libraries like react-router
, headlessui
, Radix UI
.
const Tabs = ({ children }) => <div>{children}</div>;
Tabs.Tab = ({ children }) => <button>{children}</button>;
Tabs.Panel = ({ children }) => <div>{children}</div>;
<Tabs>
<Tabs.Tab>🏠 Home</Tabs.Tab>
<Tabs.Tab>👤 Profile</Tabs.Tab>
<Tabs.Panel>Content for Home</Tabs.Panel>
<Tabs.Panel>Content for Profile</Tabs.Panel>
</Tabs>;
✅ Real-world: Dropdown menus, modals, stepper forms.
6️⃣ Context API / Provider Pattern 🌐
Used to share state globally without prop drilling.
👉 Use Case: Themes, authentication, global settings.
const ThemeContext = createContext("light");
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
const ThemedButton = () => {
const { theme } = useContext(ThemeContext);
return <button>{theme === "light" ? "☀️ Light Mode" : "🌙 Dark Mode"}</button>;
};
✅ Real-world: Dark/light mode, user sessions, language switch.
7️⃣ Controlled vs Uncontrolled Components 🎛️
- Controlled: Form values controlled via React state.
- Uncontrolled: Form values accessed via refs.
👉 Use Case: Controlled for validation, uncontrolled for performance/simple forms.
// Controlled
<input value={value} onChange={(e) => setValue(e.target.value)} />
// Uncontrolled
<input ref={ref} />
✅ Real-world:
- ✅ Controlled: Sign-up form with live validation.
- ✅ Uncontrolled: File upload input.
8️⃣ State Reducer Pattern ⚙️
Allow consumers to control internal state transitions (inspired by Redux).
👉 Use Case: Complex reusable components where users need control.
function useToggle({ reducer = (s, a) => !s } = {}) {
const [on, dispatch] = useReducer(reducer, false);
return [on, () => dispatch()];
}
✅ Real-world: Customizable toggle, dropdown, or modal logic.
9️⃣ Controlled Props Pattern 🎚️
Component accepts both internal and external state control.
👉 Use Case: Library components needing flexible usage.
const Toggle = ({ on: controlledOn, onChange }) => {
const [uncontrolledOn, setOn] = useState(false);
const isControlled = controlledOn !== undefined;
const on = isControlled ? controlledOn : uncontrolledOn;
const toggle = () => {
if (isControlled) onChange(!on);
else setOn(!on);
};
return <button onClick={toggle}>{on ? "✅ ON" : "❌ OFF"}</button>;
};
✅ Real-world: Reusable toggle, form components, inputs.
🔟 Hooks State Machine Pattern 🕹️
Model component behavior with finite state machines.
👉 Use Case: Complex UI workflows with multiple states.
function useToggleMachine() {
const [state, setState] = useState("off");
const toggle = () => setState(state === "off" ? "on" : "off");
return { state, toggle };
}
✅ Real-world: Payment flows 💳, multi-step onboarding 🪜, authentication 🔑.
🧭 Choosing the Right React Pattern
flowchart TD
A[Start: Need to Share or Reuse Logic?] -->|Yes| B[Custom Hook]
A -->|No| C[Need to Reuse UI?]
C -->|Yes| D[Compound Components]
C -->|No| E[Complex State Sharing?]
E -->|Yes| F[Context API / Provider Pattern]
E -->|No| G[State Local to Component]
B --> H[Hook Reusable Across Components]
D --> I[Flexible & Composable UI]
F --> J[Global State or Theme]
G --> K[Simple useState Hook]
🏁 Final Thoughts ✨
Patterns are not just “nice to know”—they’re what separate good React developers from great ones. By mastering them, you’ll build apps that scale gracefully, are easier to maintain, and provide cleaner APIs for your team and future self. 💡
🔥 Start small, refactor incrementally, and let patterns emerge naturally.
📝 About the Author
Written by Yogesh Bamanier Senior Frontend Developer | React.js Expert | Open-Source Contributor Passionate about building scalable React applications and sharing knowledge with the dev community. 🚀
🏷️📢 Happy-Learning...
- #reactjs
- #javascript
- #frontend
- #webdev
- #reactpatterns
- #hooks
Top comments (3)
**QuickyNews:
**Yogesh Bamanier's article on DEV Community delves into essential React design patterns that enhance scalability, reusability, and maintainability in applications. Key patterns discussed include:
-** Container & Presentational Components**: Separating logic and UI for cleaner code.
These patterns are crucial for building robust and maintainable React applications.
@quiazine correcttt.....
Will try to change code snippet next time.