React introduced hooks to bring state management, side effects, and performance optimizations to functional components. Among the most important ones are useEffect, useReducer, and useMemo.
Let’s explore them in detail with icons, syntax, examples, and best practices.
⚡ useEffect – Side Effects
🛠 What does it do?
- Handles side effects (things outside the component’s render).
- Examples include data fetching, subscriptions, timers, and manual DOM updates.
📑 Syntax
useEffect(() => {
// effect logic here
return () => {
// cleanup logic here (optional)
};
}, [dependencies]);
📌 Explanation of Dependencies
- [] empty array: Runs only once (like componentDidMount).
- [state, props]: Runs when listed values change.
- No array: Runs after every render.
🖼 Example
import { useState, useEffect } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(timer); // cleanup
}, []);
return <h1>Time: {count}s</h1>;
}
✅ Best Use Cases
- Fetching API data.
- Setting up subscriptions (WebSocket, Firebase, etc.).
- Handling intervals/timers.
- Cleaning up on unmount.
🎛 useReducer – Complex State Management
🛠 What does it do?
- Manages complex or structured state in components.
- Works with a reducer function that defines how state updates happen.
- Inspired by Redux but scoped to the component.
📑 Syntax
const [state, dispatch] = useReducer(reducer, initialState);
📌 Reducer Function
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
🖼 Example
import { useReducer } from "react";
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
<h1>Count: {state.count}</h1>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</>
);
}

Join the conversation! Your thoughts help the community grow.