React
/Intermediate
Side Effects (useEffect)
Definition
The `useEffect` hook lets you perform side effects in functional components. A side effect is anything that reaches outside the React component (like fetching data, manually changing the DOM, or setting up subscriptions).
Explain Like I'm New
React's main job is just turning data into UI. But sometimes you need to do things outside of that process, like knocking on a server's door to ask for data, or setting up a ticking clock. `useEffect` is a designated safe space where you can do these 'outside' tasks after React has safely finished painting the screen.
Real World Example
When a 'Profile' component appears on screen, you need to fetch that user's data from a database. You put the fetch request inside `useEffect` so it runs exactly once when the profile loads.
Common Use Cases
- •Fetching data from an API on component mount
- •Setting up event listeners (like window resize)
- •Interacting with non-React libraries (like a D3 chart)
Dependency Array Behaviors
| Array Type | Example | When does the effect run? |
|---|---|---|
| No Array | `useEffect(() => {...})` | Runs on the very first render AND after absolutely every single re-render of the component. (High risk of infinite loops). |
| Empty Array | `useEffect(() => {...}, [])` | Runs strictly ONCE when the component mounts to the screen. Never runs again. |
| Variables Included | `useEffect(() => {...}, [id])` | Runs on the first render, and then ONLY runs again if the value of `id` has mathematically changed. |
Interactive Example
import React, { useState, useEffect } from 'react'; export default function Timer() { const [seconds, setSeconds] = useState(0); // This effect runs exactly ONCE on mount because of [] useEffect(() => { console.log("Timer started!"); // Set up a side effect (an interval) const intervalId = setInterval(() => { setSeconds(prev => prev + 1); }, 1000); // Cleanup Function // Runs when the component unmounts (is removed from screen) return () => { console.log("Component destroyed, clearing interval!"); clearInterval(intervalId); }; }, []); // Empty dependency array return ( <div> <h2>Seconds elapsed: {seconds}</h2> </div> ); }
Interview Questions
basic
- What is the dependency array in useEffect?
- What happens if you leave the dependency array completely empty `[]`?
intermediate
- What happens if you don't provide a dependency array at all?
- What is the cleanup function in useEffect and when does it run?
advanced
- Why shouldn't you make the useEffect callback itself an `async` function?
- How do you deal with 'stale closures' inside useEffect?
trick
- If you set state inside a useEffect that has no dependency array, what happens?