Bird
Raised Fist0
Reactframework~10 mins

What is useEffect in React - Visual Explanation

Choose your learning style10 modes available
Concept Flow - What is useEffect
Component Renders
↓
useEffect Runs
↓
Effect Code Executes
↓
Optional Cleanup Runs
↓
Wait for Next Render or Dependency Change
↩Back to useEffect Runs if dependencies change
Shows how useEffect runs after the component renders, executes its code, optionally cleans up, and waits for dependency changes to run again.
Execution Sample
React
import React, { useState, useEffect } from 'react';

function Timer() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setCount(c => c + 1), 1000);
    return () => clearInterval(id);
  }, []);
  return <div>{count}</div>;
}
A timer component that increases count every second using useEffect to set up and clean up the interval.
Execution Table
StepTriggerState BeforeActionState AfterWhat Re-rendersDOM Change
1Initial rendercount=0Render component, schedule useEffectcount=0Timer component<div>0</div>
2After rendercount=0Run useEffect: setInterval startscount=0No re-render yetNo change
31 second passescount=0Interval callback: setCount(1)count=1Timer component<div>1</div>
4Re-render due to state changecount=1Render component, useEffect dependencies unchangedcount=1Timer component<div>1</div>
5Another second passescount=1Interval callback: setCount(2)count=2Timer component<div>2</div>
6Component unmountscount=2Cleanup: clearInterval calledcount=2No re-renderNo change
💡 Component unmounts, cleanup runs, interval stops.
Variable Tracker
VariableStartAfter Step 1After Step 3After Step 5Final
count00122
intervalIdundefinedsetsetsetcleared
Key Moments - 3 Insights
Why does useEffect run after the component renders and not before?
useEffect runs after rendering so it can safely interact with the DOM or perform side effects without blocking the UI update, as shown in step 2 where it runs after the initial render.
What happens if the dependency array is empty?
The effect runs only once after the first render and cleans up on unmount, as seen in steps 2 and 6 where the interval is set once and cleared on unmount.
Why does the component re-render when setCount is called inside useEffect?
Calling setCount updates state, triggering a re-render to show the new count value, demonstrated in steps 3 and 5 where count changes cause re-renders.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of count at Step 4?
A0
B1
C2
Dundefined
💡 Hint
Check the 'State After' column at Step 3 and Step 4 in the execution_table.
At which step does the cleanup function run?
AStep 6
BStep 4
CStep 2
DStep 3
💡 Hint
Look for the step mentioning 'Cleanup' in the 'Action' column.
If the dependency array was omitted, how would the execution table change?
AuseEffect would run only once after initial render
BCleanup would never run
CuseEffect would run after every render
DState would never update
💡 Hint
Think about how useEffect behaves without dependencies, referencing the 'Trigger' column.
Concept Snapshot
useEffect(() => { effect }, [deps])
- Runs effect after render
- Runs again if deps change
- Cleanup runs before next effect or unmount
- Used for side effects like timers, fetch
- Empty deps = run once after first render
Full Transcript
useEffect is a React hook that runs code after the component renders. It lets you perform side effects like starting timers or fetching data. The effect runs after the DOM updates, so it doesn't block the UI. You can give it a list of dependencies to control when it runs again. If the list is empty, it runs only once after the first render. You can also return a cleanup function to run before the effect runs again or when the component unmounts. In the example, useEffect sets up a timer that updates count every second and cleans up the timer when the component is removed.

Practice

(1/5)
1. What is the primary purpose of useEffect in React?
easy
A. To declare state variables inside a component
B. To create new components dynamically
C. To run code after the component renders or when data changes
D. To style components with CSS

Solution

  1. Step 1: Understand what useEffect does

    useEffect runs code after the component renders or when specified data changes.
  2. Step 2: Compare with other React features

    State variables declare data, styling is CSS, and creating components is unrelated to useEffect.
  3. Final Answer:

    To run code after the component renders or when data changes -> Option C
  4. Quick Check:

    useEffect runs code after render or data change [OK]
Hint: useEffect runs after render or data updates [OK]
Common Mistakes:
  • Confusing useEffect with useState
  • Thinking useEffect styles components
  • Believing useEffect creates components
2. Which of the following is the correct syntax to use useEffect that runs only once after the first render?
easy
A. useEffect(() => { console.log('Hello'); });
B. useEffect(() => { console.log('Hello'); }, []);
C. useEffect(() => { console.log('Hello'); }, true);
D. useEffect(() => { console.log('Hello'); }, null);

Solution

  1. Step 1: Identify how to run useEffect once

    Passing an empty array [] as dependency makes useEffect run only once after the first render.
  2. Step 2: Check other options

    Without dependencies (useEffect(() => { console.log('Hello'); });), it runs after every render. Options B and C pass non-array values, causing the effect to run after every render (with a React warning).
  3. Final Answer:

    useEffect(() => { console.log('Hello'); }, []); -> Option B
  4. Quick Check:

    Empty dependency array means run once [OK]
Hint: Empty array runs useEffect once after first render [OK]
Common Mistakes:
  • Omitting dependency array causes repeated runs
  • Passing non-array values thinking it runs once
  • Confusing [] with null or true
3. What will be logged to the console when this component runs?
import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Count is:', count);
  }, [count]);

  return (
    <button onClick={() => setCount(count + 1)}>Increment</button>
  );
}
medium
A. Logs 'Count is: 0' and then logs updated count each time button clicked
B. Logs 'Count is: 0' once after first render only
C. Logs nothing because useEffect has no dependencies
D. Causes an infinite loop of logs

Solution

  1. Step 1: Understand useEffect with [count] dependency

    The effect runs after first render and every time count changes, logging the current count.
  2. Step 2: Analyze button click behavior

    Clicking the button increases count, triggering useEffect to log the new value.
  3. Final Answer:

    Logs 'Count is: 0' and then logs updated count each time button clicked -> Option A
  4. Quick Check:

    useEffect runs on count change, logging each update [OK]
Hint: useEffect runs after render and on dependency change [OK]
Common Mistakes:
  • Thinking useEffect runs only once without empty array
  • Believing no logs happen without empty array
  • Assuming infinite loops without setCount inside useEffect
4. Identify the problem in this code snippet using useEffect:
useEffect(() => {
  fetchData();
}, fetchData);

Assume fetchData is a function defined outside.
medium
A. No problem, this code is correct
B. fetchData cannot be called inside useEffect
C. useEffect must not have any dependencies
D. Dependency array should be an array, not a function

Solution

  1. Step 1: Check dependency argument type

    The second argument to useEffect must be an array listing dependencies, not a function.
  2. Step 2: Identify correct syntax

    It should be [fetchData] if fetchData is a dependency, not just fetchData alone.
  3. Final Answer:

    Dependency array should be an array, not a function -> Option D
  4. Quick Check:

    useEffect dependencies must be an array [OK]
Hint: Dependency argument must be an array, not a function [OK]
Common Mistakes:
  • Passing a function instead of an array as dependencies
  • Ignoring dependency array causing repeated runs
  • Thinking useEffect cannot call functions
5. You want to fetch user data only once when a component mounts and clean up a subscription when it unmounts. Which useEffect pattern is correct?
useEffect(() => {
  const subscription = subscribeToUserData();
  fetchUserData();
  return () => {
    subscription.unsubscribe();
  };
}, []);
hard
A. This pattern correctly fetches once and cleans up on unmount
B. Missing dependency array causes multiple fetches
C. Cleanup function should not be returned inside useEffect
D. Subscription should be created inside cleanup function

Solution

  1. Step 1: Check dependency array usage

    Empty array [] ensures effect runs once on mount and cleanup on unmount.
  2. Step 2: Verify cleanup function correctness

    Returning a function that unsubscribes cleans up resources properly when component unmounts.
  3. Final Answer:

    This pattern correctly fetches once and cleans up on unmount -> Option A
  4. Quick Check:

    Empty array + cleanup function = run once + cleanup [OK]
Hint: Empty array runs once; return cleanup function for unmount [OK]
Common Mistakes:
  • Omitting cleanup function causing memory leaks
  • Not using empty array causing repeated fetches
  • Placing subscription inside cleanup function incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard