useEffect & Component Lifecycle
What is a side effect?
Rendering should be pure: given props and state, return UI. But apps also need to do things outside rendering — fetch data, start a timer, subscribe to events. These are side effects, and the useEffect hook is where they belong.
The shape of useEffect
import { useEffect, useState } from 'react';
function Clock() {
const [time, setTime] = useState(new Date());
useEffect(() => {
const id = setInterval(() => setTime(new Date()), 1000);
return () => clearInterval(id); // cleanup when the component leaves
}, []); // [] = run once, on mount
return <Text>{time.toLocaleTimeString()}</Text>;
}
Three parts: the effect function (what to do), an optional cleanup function it returns (undo it), and the dependency array (when to run).
The dependency array controls timing
[]— run once, when the component first appears (mounts).[userId]— run on mount and again wheneveruserIdchanges.- no array — run after every render (rarely what you want).
Fetching data with useEffect
function Profile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
let active = true;
fetch(`https://api.example.com/users/${userId}`)
.then(res => res.json())
.then(data => { if (active) setUser(data); });
return () => { active = false; }; // avoid setting state after unmount
}, [userId]); // refetch when userId changes
if (!user) return <Text>Loading...</Text>;
return <Text>{user.name}</Text>;
}
Why cleanup matters
If you start a timer, a subscription, or a network request, you must stop it when the component leaves — otherwise you leak resources or try to update a component that’s gone (a common warning). The returned cleanup function handles this.
The rules of hooks
- Only call hooks at the top level of a component — never inside loops, conditions or nested functions.
- Only call hooks from React components or custom hooks.
These rules let React reliably track each hook between renders.
Common mistakes
- Forgetting the dependency array, causing an infinite fetch/render loop.
- Missing a dependency the effect uses (stale data).
- Not returning a cleanup for timers/subscriptions (leaks and warnings).
Summary: useEffect runs side effects like data fetching and timers. Control when it runs with the dependency array, and return a cleanup function to undo subscriptions/timers. Follow the rules of hooks.