Lesson 7 of 20Article16 min
useState & useEffect Hooks
useState stores data that changes over time — taps, form input, API responses. useEffect runs side effects after render — fetching data, subscriptions, timers. Together they replace class component lifecycle methods.
State and side effects in functional components
useState stores data that changes over time — taps, form input, API responses. useEffect runs side effects after render — fetching data, subscriptions, timers. Together they replace class component lifecycle methods.
State update flow
useState patterns
Counter and object state
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: "", age: 0 });
// Functional update — safe when new state depends on old
setCount((prev) => prev + 1);
// Object update — always spread, never mutate
setUser((prev) => ({ ...prev, name: "Alex" }));useEffect patterns
Fetch on mount and cleanup
useEffect(() => {
let cancelled = false;
async function load() {
const res = await fetch("https://api.example.com/posts");
const data = await res.json();
if (!cancelled) setPosts(data);
}
load();
return () => { cancelled = true; }; // cleanup on unmount
}, []); // empty deps = run once on mountRules of hooks
- Only call hooks at the top level — not inside loops, conditions, or nested functions.
- Only call hooks from React function components or custom hooks.
- Dependency array controls when useEffect re-runs — include all values used inside.