React useEffect Interview Guide
What is useEffect?
Section titled “What is useEffect?”useEffect is a React Hook used to perform side effects in functional components.
Common use cases:
- API calls
- Event listeners
- Timers
- DOM manipulation
- Subscriptions
useEffect(() => { console.log("Component rendered");});It runs after the component renders.
Syntax
Section titled “Syntax”useEffect(() => { // Side Effect
return () => { // Cleanup };}, [dependencies]);- First argument -> effect function
- Return function -> cleanup
- Second argument -> dependency array
When does useEffect execute?
Section titled “When does useEffect execute?”useEffect(() => { console.log("Executed");});Runs:
- After the first render
- After every re-render
Running Only Once
Section titled “Running Only Once”useEffect(() => { getUsers();}, []);An empty dependency array means the effect runs only after the initial render, similar to componentDidMount().
Running When State Changes
Section titled “Running When State Changes”useEffect(() => { console.log("Count changed");}, [count]);Runs:
- On initial render
- Whenever
countchanges
Lifecycle Mapping
Section titled “Lifecycle Mapping”componentDidMount
Section titled “componentDidMount”useEffect(() => { fetchData();}, []);componentDidUpdate
Section titled “componentDidUpdate”useEffect(() => { console.log("Updated");}, [count]);componentWillUnmount
Section titled “componentWillUnmount”useEffect(() => { return () => { console.log("Cleanup"); };}, []);Can one useEffect replace all lifecycle methods?
Section titled “Can one useEffect replace all lifecycle methods?”Yes. Multiple effects are recommended.
useEffect(() => { fetchUsers();}, []);
useEffect(() => { updateTitle();}, [count]);
useEffect(() => { return () => { cleanup(); };}, []);Dependency Arrays
Section titled “Dependency Arrays”No Dependency Array
Section titled “No Dependency Array”useEffect(() => { console.log("Effect");});Runs after every render.
Empty Dependency Array
Section titled “Empty Dependency Array”useEffect(() => { console.log("Once");}, []);Runs only once after mounting.
Multiple Dependencies
Section titled “Multiple Dependencies”useEffect(() => { console.log("Changed");}, [name, age]);Runs whenever name or age changes.
Why include dependencies?
Section titled “Why include dependencies?”Incorrect:
useEffect(() => { console.log(count);}, []);Correct:
useEffect(() => { console.log(count);}, [count]);Including dependencies avoids stale values.
Cleanup Functions
Section titled “Cleanup Functions”Basic Cleanup
Section titled “Basic Cleanup”useEffect(() => { return () => { console.log("Cleanup"); };}, []);Cleanup prevents:
- Memory leaks
- Duplicate subscriptions
- Unnecessary resource usage
Event Listener Cleanup
Section titled “Event Listener Cleanup”useEffect(() => { const handleResize = () => {};
window.addEventListener("resize", handleResize);
return () => { window.removeEventListener("resize", handleResize); };}, []);Interval Cleanup
Section titled “Interval Cleanup”useEffect(() => { const id = setInterval(() => { console.log("Running"); }, 1000);
return () => clearInterval(id);}, []);API Calls
Section titled “API Calls”Fetching Data
Section titled “Fetching Data”useEffect(() => { fetch("/users") .then(res => res.json()) .then(data => setUsers(data));}, []);API calls are side effects and belong inside useEffect.
Async Effects
Section titled “Async Effects”Incorrect:
useEffect(async () => {}, []);Correct:
useEffect(() => { const loadData = async () => { const res = await fetch("/users"); };
loadData();}, []);Senior-Level Questions
Section titled “Senior-Level Questions”Infinite Re-renders
Section titled “Infinite Re-renders”useEffect(() => { setCount(count + 1);}, [count]);flowchart TD A[Count changes] --> B[useEffect executes] B --> C["setCount()"] C --> D[Component re-renders] D --> A
Avoid this by using an appropriate dependency array and preventing unnecessary state updates.
Stale Closures
Section titled “Stale Closures”Problem:
useEffect(() => { const id = setInterval(() => { console.log(count); }, 1000);}, []);Solution:
useEffect(() => { const id = setInterval(() => { setCount(prev => prev + 1); }, 1000);
return () => clearInterval(id);}, []);useEffect vs useLayoutEffect
Section titled “useEffect vs useLayoutEffect”useEffect |
useLayoutEffect |
|---|---|
| Runs after paint | Runs before paint |
| Non-blocking | Blocking |
| Best for API calls | Best for DOM measurements |
| Better performance | Use sparingly |
Example:
useLayoutEffect(() => { console.log(element.offsetWidth);}, []);Why use multiple effects?
Section titled “Why use multiple effects?”Avoid unrelated logic in one effect.
Less maintainable:
useEffect(() => { fetchUsers(); updateTitle(); setupListener();}, []);Better:
useEffect(fetchUsers, []);useEffect(updateTitle, [count]);useEffect(setupListener, []);Dependency Comparison
Section titled “Dependency Comparison”React compares dependency values using Object.is().
Primitives:
count === countObjects and arrays:
{} !== {}[] !== []New object references cause effects to run.
Stabilizing Object References
Section titled “Stabilizing Object References”const user = useMemo(() => ({ name: "John"}), []);
useEffect(() => {}, [user]);Execution Order
Section titled “Execution Order”function App() { console.log("Render");
useEffect(() => { console.log("Effect"); }, []);
return <div>Hello</div>;}Output:
RenderEffectsequenceDiagram participant R as React participant C as Component R->>C: Render component C-->>R: Return JSX R->>R: Paint UI R->>C: Execute useEffect
One-Line Interview Answer
Section titled “One-Line Interview Answer”
useEffectis a React Hook used to perform side effects after rendering. It can replicatecomponentDidMount,componentDidUpdate, andcomponentWillUnmountusing dependency arrays and cleanup functions.
Key Takeaways
Section titled “Key Takeaways”useEffecthandles side effects after rendering.- Dependency arrays determine when an effect executes.
- Cleanup functions prevent memory leaks and remove subscriptions.
- Avoid infinite loops by managing state updates and dependencies carefully.
- Prefer multiple focused effects over one large effect.