Topic 27 of 54
The Dependency Array
Overview
The dependency array `[]` is the second argument to `useEffect`. It is the control valve for your effect. It tells React exactly which variables to watch. If any variable inside the array changes between renders, the effect runs again. If nothing changes, the effect is skipped, saving performance.
Syntax
Leaving the array off entirely is usually a mistake and causes infinite loops if your effect also updates state. Most commonly, you will use `[]` for initial setup, or `[variable]` for reacting to changes.
The Three Forms of Dependencies
jsx
// 1. NO Array: Runs on EVERY single render
useEffect(() => {
console.log("I run after every render!");
});
// 2. EMPTY Array: Runs EXACTLY ONCE (on mount)
useEffect(() => {
console.log("I run only once when the component first appears.");
}, []);
// 3. FILLED Array: Runs on mount AND whenever 'id' changes
useEffect(() => {
console.log("I run when the component appears, and when 'id' changes.");
}, [id]);Common Pitfalls
- Lying to React about dependencies. If you use a prop or state variable inside the effect but don't list it in the array, your effect will use 'stale' (old) data. Always listen to the `react-hooks/exhaustive-deps` ESLint rule.
Interview Tips
- You will be asked: 'What happens if you leave out the dependency array entirely?' Answer: The effect runs after every single render. If that effect updates state, it triggers a new render, causing an infinite loop!
Real-World Example
Fetching user data when the selected user ID changes.
example
jsx
function UserProfile({ userId }) {
const [userData, setUserData] = useState(null);
useEffect(() => {
// If we forgot to put userId in the array, it would only fetch once (for the first user),
// and would never update if the parent passed a new userId!
fetch(`/api/users/${userId}`).then(res => setUserData(res));
}, [userId]);
return <div>{userData?.name}</div>;
}