Loading lessons...
Dependency Array Rules
Dependency Array Rules
By default, useEffect runs after every render. Passing a dependency array as the second argument controls precisely when the effect callback should re-run.
The Three Behaviors of Dependency Arrays
1. No Dependency Array (Runs after EVERY render)
If you omit the second argument entirely, the effect executes after every single render and re-render.
useEffect(() => {
console.log("Runs after initial mount AND every re-render!");
});
2. Empty Dependency Array [] (Runs ONCE on Mount)
Passing an empty array [] tells React that the effect relies on no reactive state or props, so it executes only once when the component first mounts.
useEffect(() => {
console.log("Runs ONLY ONCE when component mounts.");
}, []); // Empty dependency array
3. Array with Specific Dependencies [dep1, dep2] (Runs on Mount + Changes)
Passing values inside the array tells React to run the effect on mount, and then re-run it only if any specified dependency value changes between renders.
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(data => setUser(data));
}, [userId]); // Re-runs whenever userId prop changes!
return <div>{user ? user.name : "Loading..."}</div>;
}
Exhaustive Dependencies Rule
Always include all props, state, and reactive values used inside the effect function in the dependency array. Omitting dependencies leads to stale state bugs.
Summary & TL;DR
- No array: Effect runs after every render.
- Empty array
[]: Effect runs once when component mounts. - Dependency array
[a, b]: Effect runs on mount and whenaorbchange. - Never lie to the dependency array—include all reactive variables referenced inside the effect.