Bird
Raised Fist0
Reactframework~15 mins

Multiple effects in a component in React - Deep Dive

Choose your learning style10 modes available
Overview - Multiple effects in a component
What is it?
In React, a component can have multiple effects using the useEffect hook. Each effect runs independently and can handle different tasks like fetching data, updating the document title, or setting up event listeners. This helps keep code organized and focused on one job per effect. Multiple effects run in the order they are declared inside the component.
Why it matters
Without multiple effects, all side tasks would be mixed in one place, making code hard to read and maintain. Separating concerns into multiple effects makes debugging easier and prevents bugs caused by unrelated logic interfering. It also improves performance by running only the necessary effect when its dependencies change.
Where it fits
Before learning this, you should understand React functional components and the basic useEffect hook. After this, you can learn advanced hooks patterns, custom hooks, and performance optimization techniques in React.
Mental Model
Core Idea
Multiple useEffect hooks let a component handle different side tasks separately and clearly.
Think of it like...
It's like having different helpers in a kitchen: one handles chopping vegetables, another boils water, and another sets the table. Each helper focuses on one job, making the whole meal preparation smooth and organized.
Component
  ├─ useEffect #1: fetch data
  ├─ useEffect #2: update title
  └─ useEffect #3: event listener

Each effect runs independently in order.
Build-Up - 6 Steps
1
FoundationUnderstanding useEffect basics
🤔
Concept: Learn what useEffect does and how it runs after rendering.
useEffect is a React hook that runs a function after the component renders. It can run once, on every render, or when specific values change. It helps perform side tasks like fetching data or updating the page title.
Result
You can run code after the component shows on screen, reacting to changes.
Understanding useEffect is key because it controls when and how side tasks happen in React components.
2
FoundationSingle effect with dependencies
🤔
Concept: Learn how to run an effect only when certain values change.
By passing a dependency array to useEffect, React runs the effect only when those values change. For example, useEffect(() => { /* code */ }, [count]) runs only when count changes.
Result
Effects run efficiently, avoiding unnecessary work on every render.
Knowing dependencies lets you control effect timing and avoid performance issues.
3
IntermediateUsing multiple useEffect hooks
🤔Before reading on: do you think multiple useEffect hooks run together or one cancels the other? Commit to your answer.
Concept: A component can have many useEffect hooks, each for a different task.
Instead of putting all side tasks in one useEffect, split them into multiple hooks. For example, one effect fetches data, another updates the document title, and another sets up event listeners. React runs them in the order they appear.
Result
Code is cleaner and each effect focuses on one responsibility.
Understanding that effects are independent helps organize code and avoid bugs from mixing unrelated logic.
4
IntermediateEffect cleanup with multiple effects
🤔Before reading on: do you think cleanup functions from multiple effects run all or only one? Commit to your answer.
Concept: Each useEffect can return a cleanup function to undo its work when dependencies change or component unmounts.
When you have multiple effects, each cleanup runs separately. For example, one effect might remove an event listener, another might cancel a timer. React calls cleanup functions before running the effect again or when the component leaves the screen.
Result
Resources are freed properly and side effects don't pile up.
Knowing cleanup runs per effect prevents memory leaks and unexpected behavior.
5
AdvancedOrdering and timing of multiple effects
🤔Before reading on: do you think useEffect hooks run in the order declared or randomly? Commit to your answer.
Concept: React runs multiple useEffect hooks in the order they appear after rendering completes.
Effects run after the DOM updates, one after another in declaration order. Cleanup functions run before the next effect or on unmount. This predictable order helps when effects depend on each other or shared state.
Result
You can reason about side effects timing and avoid race conditions.
Understanding effect order helps coordinate complex side effects safely.
6
ExpertPerformance and pitfalls with multiple effects
🤔Before reading on: do you think splitting effects always improves performance? Commit to your answer.
Concept: While multiple effects improve clarity, too many or poorly managed effects can hurt performance or cause bugs.
Each effect adds overhead. If effects share dependencies or cause repeated renders, it can slow the app. Also, effects that update state can trigger other effects, causing loops. Experts carefully design dependencies and combine effects when needed to balance clarity and efficiency.
Result
Well-structured effects improve maintainability without sacrificing speed.
Knowing when to combine or separate effects is key to writing robust, performant React components.
Under the Hood
React keeps a list of all useEffect hooks declared in a component. After rendering, React runs each effect's function in order. If an effect returns a cleanup function, React stores it and calls it before the next effect run or when the component unmounts. React tracks dependencies to decide when to rerun each effect, avoiding unnecessary work.
Why designed this way?
React designed useEffect to separate side effects from rendering logic, improving code clarity and preventing blocking UI updates. Allowing multiple effects lets developers organize code by concern. The cleanup mechanism prevents resource leaks. This design balances simplicity, flexibility, and performance.
Component Render
  │
  ├─ useEffect #1 run → stores cleanup #1
  ├─ useEffect #2 run → stores cleanup #2
  └─ useEffect #3 run → stores cleanup #3

On update:
  ├─ cleanup #1 run
  ├─ useEffect #1 run
  ├─ cleanup #2 run
  ├─ useEffect #2 run
  └─ cleanup #3 run
     useEffect #3 run
Myth Busters - 4 Common Misconceptions
Quick: Do multiple useEffect hooks merge into one or run separately? Commit to your answer.
Common Belief:All useEffect hooks combine into a single effect that runs together.
Tap to reveal reality
Reality:Each useEffect hook runs independently in the order declared.
Why it matters:Believing they merge can cause confusion when effects behave differently or cleanup runs unexpectedly.
Quick: Does useEffect run before or after rendering? Commit to your answer.
Common Belief:useEffect runs before the component renders to prepare things.
Tap to reveal reality
Reality:useEffect runs after the component renders and the DOM updates.
Why it matters:
Quick: Does cleanup run only on unmount or also on dependency change? Commit to your answer.
Common Belief:Cleanup functions run only when the component unmounts.
Tap to reveal reality
Reality:Cleanup runs before the effect reruns due to dependency changes and on unmount.
Why it matters:Misunderstanding cleanup timing can cause resource leaks or duplicated event listeners.
Quick: Does splitting effects always improve performance? Commit to your answer.
Common Belief:More useEffect hooks always make the app faster and cleaner.
Tap to reveal reality
Reality:Too many effects or poorly managed dependencies can cause extra renders and slowdowns.
Why it matters:Assuming more effects are always better can lead to inefficient code and bugs.
Expert Zone
1
Effects with overlapping dependencies can cause subtle bugs if their cleanup and setup order is not carefully managed.
2
React batches state updates triggered inside effects, but effects themselves run sequentially, which can affect timing-sensitive logic.
3
Custom hooks often combine multiple effects internally, hiding complexity but requiring careful dependency management.
When NOT to use
Avoid multiple effects when side tasks are tightly coupled and share dependencies; instead, combine them into one effect to reduce overhead. For synchronous logic or derived state, useMemo or useCallback may be better alternatives.
Production Patterns
In real apps, developers separate data fetching, subscriptions, and UI updates into distinct effects. They use custom hooks to encapsulate complex effect logic and carefully manage dependencies to prevent infinite loops or stale data.
Connections
Event-driven programming
Multiple effects resemble separate event handlers reacting to different triggers.
Understanding event-driven design helps grasp why separating effects improves clarity and responsiveness.
Unix shell pipelines
Like chaining commands where each does one job, multiple effects chain side tasks cleanly.
This connection shows how breaking tasks into small steps improves maintainability and debugging.
Project management (task delegation)
Assigning different effects to handle specific tasks is like delegating work to team members.
Knowing this helps appreciate how separation of concerns reduces errors and improves collaboration.
Common Pitfalls
#1Combining unrelated side effects in one useEffect.
Wrong approach:useEffect(() => { fetchData(); document.title = `Count: ${count}`; }, [count]);
Correct approach:useEffect(() => { fetchData(); }, []); useEffect(() => { document.title = `Count: ${count}`; }, [count]);
Root cause:Misunderstanding that effects can and should be split by responsibility.
#2Forgetting to add dependencies, causing stale data or infinite loops.
Wrong approach:useEffect(() => { setTimeout(() => console.log(count), 1000); }, []);
Correct approach:useEffect(() => { setTimeout(() => console.log(count), 1000); }, [count]);
Root cause:Not realizing dependencies control when effects rerun and capture fresh values.
#3Not cleaning up event listeners in effects.
Wrong approach:useEffect(() => { window.addEventListener('resize', handleResize); }, []);
Correct approach:useEffect(() => { window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []);
Root cause:Ignoring cleanup leads to memory leaks and multiple handlers stacking.
Key Takeaways
Multiple useEffect hooks let you organize side effects by their specific tasks, improving code clarity and maintainability.
Each useEffect runs independently and in the order declared, with its own cleanup function to manage resources safely.
Properly managing dependencies in each effect prevents bugs like stale data, infinite loops, or unnecessary reruns.
While splitting effects helps organization, too many or poorly designed effects can hurt performance and cause bugs.
Understanding the lifecycle and timing of effects is essential for building robust, efficient React components.

Practice

(1/5)
1. What is the main benefit of using multiple useEffect hooks in a React component?
easy
A. It combines all side effects into one function for faster execution.
B. It separates different side effects for better readability and maintenance.
C. It prevents the component from rendering multiple times.
D. It automatically optimizes the component's performance.

Solution

  1. Step 1: Understand the purpose of multiple useEffect hooks

    Multiple useEffect hooks allow you to separate different side effects logically in a component.
  2. Step 2: Recognize the benefit of separation

    This separation makes the component easier to read and maintain because each effect handles a specific task.
  3. Final Answer:

    It separates different side effects for better readability and maintenance. -> Option B
  4. Quick Check:

    Multiple effects = separation and clarity [OK]
Hint: Multiple effects separate tasks for clarity and easier updates [OK]
Common Mistakes:
  • Thinking multiple effects combine tasks into one
  • Believing multiple effects prevent re-renders
  • Assuming multiple effects auto-optimize performance
2. Which of the following is the correct syntax to use two separate useEffect hooks in a React functional component?
easy
A. useEffect(() => { /* effect 1 */ }, []); useEffect(() => { /* effect 2 */ }, []);
B. useEffect(() => { /* effect 1 */ }, []) useEffect(() => { /* effect 2 */ }, []);
C. useEffect(() => { /* effect 1 */ } useEffect(() => { /* effect 2 */ });
D. useEffect(() => { /* effect 1 */ }, [] && []) useEffect(() => { /* effect 2 */ }, []);

Solution

  1. Step 1: Recall correct useEffect syntax

    The useEffect hook takes a function and a dependency array as arguments, separated by a comma.
  2. Step 2: Identify correct separation of two hooks

    Two separate useEffect hooks should be called one after another, each with its own function and dependency array, ending with semicolons.
  3. Final Answer:

    useEffect(() => { /* effect 1 */ }, []); useEffect(() => { /* effect 2 */ }, []); -> Option A
  4. Quick Check:

    Separate hooks with own deps and semicolons [OK]
Hint: Each useEffect needs its own function and dependency array [OK]
Common Mistakes:
  • Using commas instead of semicolons between hooks
  • Combining dependency arrays incorrectly
  • Omitting dependency arrays causing unwanted runs
3. Consider this React component code:
function Example({ count }) {
  useEffect(() => {
    console.log('Effect A:', count);
  }, [count]);

  useEffect(() => {
    console.log('Effect B: component mounted');
  }, []);

  return <div>Count: {count}</div>;
}

What will be logged when the component first mounts with count = 5?
medium
A. Effect B: component mounted only
B. Effect B: component mounted
Effect A: 5
C. Effect A: 5 only
D. Effect A: 5
Effect B: component mounted

Solution

  1. Step 1: Understand useEffect execution order on mount

    All useEffect hooks run after the first render. They run in the order they appear in code.
  2. Step 2: Identify the order of console logs

    The first useEffect logs 'Effect A: 5', the second logs 'Effect B: component mounted'. So logs appear in code order.
  3. Final Answer:

    Effect A: 5
    Effect B: component mounted
    -> Option D
  4. Quick Check:

    Effects run in code order on mount [OK]
Hint: Effects run in code order after first render [OK]
Common Mistakes:
  • Assuming effects run in reverse order
  • Thinking effects run before render
  • Confusing dependency arrays impact on first run
4. What is wrong with this React component using multiple effects?
function Demo({ value }) {
  useEffect(() => {
    console.log('Effect 1:', value);
  }, [value]);

  useEffect(() => {
    console.log('Effect 2');
  });

  return <div>Value: {value}</div>;
}
medium
A. The first useEffect should not have a dependency array.
B. You cannot use two useEffect hooks in one component.
C. The second useEffect has no dependency array, so it runs after every render.
D. The console.log statements are invalid inside useEffect.

Solution

  1. Step 1: Check dependency arrays in useEffect hooks

    The first useEffect has a dependency array [value], so it runs only when value changes.
  2. Step 2: Analyze second useEffect without dependency array

    The second useEffect has no dependency array, so it runs after every render, which might be unintended.
  3. Final Answer:

    The second useEffect has no dependency array, so it runs after every render. -> Option C
  4. Quick Check:

    Missing deps means effect runs every render [OK]
Hint: Always add dependency array to control effect runs [OK]
Common Mistakes:
  • Thinking multiple useEffects are not allowed
  • Ignoring missing dependency arrays
  • Believing console.log is invalid inside useEffect
5. You want to fetch user data when the component mounts and also update the document title whenever the user's name changes. How should you organize your useEffect hooks?
hard
A. Use two separate useEffect hooks: one with empty deps for fetch, one with [user.name] for title.
B. Use one useEffect to fetch data and update title together with both dependencies.
C. Use one useEffect with no dependencies to do both tasks on every render.
D. Use two useEffect hooks both with empty dependency arrays.

Solution

  1. Step 1: Separate concerns with multiple useEffect hooks

    Fetching data should happen once on mount, so useEffect with empty dependency array is best.
  2. Step 2: Update document title when user.name changes

    Use a separate useEffect with [user.name] dependency to update title only when name changes.
  3. Final Answer:

    Use two separate useEffect hooks: one with empty deps for fetch, one with [user.name] for title. -> Option A
  4. Quick Check:

    Separate effects by task and dependencies [OK]
Hint: Separate effects by when and why they run [OK]
Common Mistakes:
  • Combining unrelated tasks in one effect
  • Missing dependencies causing stale updates
  • Running fetch on every render unintentionally
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