Effects let your React components do extra work like fetching data or updating the page. Knowing when effects run helps you control your app's behavior smoothly.
Effect execution timing in React
useEffect(() => {
// code to run
return () => {
// cleanup code
};
}, [dependencies]);The function inside useEffect runs after the component renders.
The optional dependencies array controls when the effect runs again.
useEffect(() => {
console.log('Runs after every render');
});useEffect(() => {
console.log('Runs only once after first render');
}, []);count value changes.useEffect(() => {
console.log('Runs when count changes:', count);
}, [count]);useEffect(() => {
const timer = setTimeout(() => {
console.log('Timer done');
}, 1000);
return () => clearTimeout(timer);
}, []);This component shows a count and a button to increase it. The effect runs after the count changes, updates the page title, and logs messages. It also cleans up before running again.
import React, { useState, useEffect } from 'react'; function TimerComponent() { const [count, setCount] = useState(0); useEffect(() => { console.log('Effect runs: count is', count); document.title = `Count: ${count}`; return () => { console.log('Cleanup for count', count); }; }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increase</button> </div> ); } export default TimerComponent;
Effects run after the browser paints the screen, so they don't block showing the UI.
Always include dependencies to avoid running effects too often or missing updates.
Cleanup functions help avoid bugs like memory leaks or duplicated timers.
Effects run after rendering to do extra work.
Dependencies array controls when effects run again.
Cleanup functions run before the effect re-runs or component unmounts.
Practice
useEffect hook run its effect function by default?Solution
Step 1: Understand default useEffect behavior
By default,useEffectruns after every render, including the first render and all updates.Step 2: Compare with other lifecycle timings
It does not run before render or only once unless dependencies are specified.Final Answer:
After every render of the component -> Option DQuick Check:
Default effect runs after render [OK]
- Thinking useEffect runs before render
- Assuming it runs only once without dependencies
- Confusing cleanup timing with effect timing
useEffect only once when the component mounts?Solution
Step 1: Identify dependency array usage
An empty array[]means the effect runs only once after the first render (mount).Step 2: Check other options
Omitting dependencies runs every render; non-empty arrays cause effect to run on changes.Final Answer:
useEffect(() => { /* effect */ }, []) -> Option CQuick Check:
Empty dependency array = run once on mount [OK]
- Omitting dependency array runs effect every render
- Using non-empty arrays thinking it runs once
- Confusing null or true as empty array
function Counter() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('Effect:', count);
return () => console.log('Cleanup:', count);
}, [count]);
return setCount(count + 1)}>Increment;
}What will be logged to the console after clicking the button twice?
Solution
Step 1: Understand effect and cleanup with dependencies
Effect runs after mount and after each count change. Cleanup runs before effect re-runs or unmount.Step 2: Trace logs on two clicks
Initial mount: Effect: 0
First click: Cleanup: 0, Effect: 1
Second click: Cleanup: 1, Effect: 2Final Answer:
Effect: 0, Cleanup: 0, Effect: 1, Cleanup: 1, Effect: 2 -> Option AQuick Check:
Effect runs after render; cleanup before next effect [OK]
- Ignoring cleanup logs
- Assuming cleanup runs after effect
- Missing initial effect run on mount
React.useEffect(() => {
const id = setInterval(() => console.log('Tick'), 1000);
return clearInterval(id);
}, []);Solution
Step 1: Check cleanup function syntax
The cleanup must be a function returning a function, but here it calls clearInterval immediately.Step 2: Correct cleanup usage
It should return a function:return () => clearInterval(id);to run cleanup on unmount.Final Answer:
The cleanup function should be a function, not the result of clearInterval -> Option BQuick Check:
Cleanup must be a function returning a function [OK]
- Returning cleanup call instead of function
- Confusing dependencies with cleanup
- Thinking setInterval needs setTimeout
propA or stateB changes, but not on every render. Which dependency array is correct?React.useEffect(() => {
// effect code
}, ???);Solution
Step 1: Understand dependency array purpose
The effect runs when any value in the array changes compared to last render.Step 2: Analyze options
[propA, stateB] lists both dependencies separately, so effect runs if either changes.
Options C and D use logical operators, which evaluate to single values and won't track changes properly.
[] runs effect only once on mount.Final Answer:
[propA, stateB] -> Option AQuick Check:
List all dependencies separately in array [OK]
- Using logical operators inside dependency array
- Leaving dependency array empty when dependencies exist
- Assuming single combined value tracks all changes
Ready to prove it?
Pass the test and this pattern moves unknown
