📖 Scenario: You are building a simple React component that tracks a count and shows when effects run during the component lifecycle. This helps understand when React runs side effects.
🎯 Goal: Create a React functional component that uses useEffect to log messages at different times: after every render, only once on mount, and when the count changes.
📋 What You'll Learn
Create a state variable count initialized to 0
Add a useEffect that runs after every render and logs 'Effect runs after every render'
Add a useEffect that runs only once on mount and logs 'Effect runs once on mount'
Add a useEffect that runs only when count changes and logs 'Effect runs when count changes'
Render a button that increments count when clicked
💡 Why This Matters
🌍 Real World
Understanding when effects run helps you manage side effects like data fetching, subscriptions, or animations in React apps.
💼 Career
React developers must control effect timing to optimize performance and avoid bugs related to stale data or unnecessary updates.
Progress0 / 4 steps
1
Set up state variable count
Create a React functional component called EffectTiming. Inside it, use useState to create a state variable called count initialized to 0.
React
Hint
Use const [count, setCount] = useState(0); inside your component.
2
Add effect that runs after every render
Inside the EffectTiming component, add a useEffect hook without dependencies that logs the string 'Effect runs after every render' to the console.
React
Hint
Use useEffect(() => { console.log('Effect runs after every render'); }); without a dependency array.
3
Add effect that runs only once on mount
Add another useEffect hook inside EffectTiming that logs 'Effect runs once on mount' to the console. Make sure it runs only once when the component mounts by passing an empty dependency array.
React
Hint
Use useEffect(() => { console.log('Effect runs once on mount'); }, []); to run once on mount.
4
Add effect that runs when count changes and a button to update count
Add a third useEffect hook that logs 'Effect runs when count changes' to the console. It should run only when count changes, so pass [count] as the dependency array. Also, add a button inside the returned JSX that increments count by 1 when clicked.
React
Hint
Use useEffect(() => { console.log('Effect runs when count changes'); }, [count]); and add a button with onClick={() => setCount(count + 1)}.
Practice
(1/5)
1. In React, when does the useEffect hook run its effect function by default?
easy
A. Only when the component unmounts
B. Before the component renders
C. Only once when the component mounts
D. After every render of the component
Solution
Step 1: Understand default useEffect behavior
By default, useEffect runs 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 D
Quick Check:
Default effect runs after render [OK]
Hint: Default useEffect runs after every render unless dependencies given [OK]
Common Mistakes:
Thinking useEffect runs before render
Assuming it runs only once without dependencies
Confusing cleanup timing with effect timing
2. Which of the following is the correct syntax to run a useEffect only once when the component mounts?
easy
A. useEffect(() => { /* effect */ }, [true])
B. useEffect(() => { /* effect */ })
C. useEffect(() => { /* effect */ }, [])
D. useEffect(() => { /* effect */ }, [null])
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 C
Quick Check:
Empty dependency array = run once on mount [OK]
Hint: Empty array runs effect once on mount [OK]
Common Mistakes:
Omitting dependency array runs effect every render
A. The effect will run multiple times because dependencies are missing
B. The cleanup function should be a function, not the result of clearInterval
C. setInterval should be replaced with setTimeout
D. The effect will never run because of missing dependencies
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 B
Quick Check:
Cleanup must be a function returning a function [OK]
Hint: Cleanup must be a function, not a direct call [OK]
Common Mistakes:
Returning cleanup call instead of function
Confusing dependencies with cleanup
Thinking setInterval needs setTimeout
5. You want a React effect to run only when either propA or stateB changes, but not on every render. Which dependency array is correct?
React.useEffect(() => {
// effect code
}, ???);
hard
A. [propA, stateB]
B. []
C. [propA || stateB]
D. [propA && stateB]
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 A
Quick Check:
List all dependencies separately in array [OK]
Hint: List each dependency separately in array to track changes [OK]
Common Mistakes:
Using logical operators inside dependency array
Leaving dependency array empty when dependencies exist
Assuming single combined value tracks all changes
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.