React Interview: Why those useEffect hooks are not working as expected?
Interview: Why those useEffect hooks are not working as expected?
import { useState, useEffect } from "react";
export default function App() {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setCount1(count1 => count1 + 1);
}, 1000);
return () => clearInterval(intervalId);
});
useEffect(() => {
const intervalId = setInterval(() => {
setCount2(count2 => count2 + 1);
}, 3000);
return () => clearInterval(intervalId);
});
return (
<div className="App">
<p>Counter 1: {count1}</p>
<p>Counter 2: {count2}</p>
</div>
);
}Expected result
In this functional component I’m creating two counters, each one increments at different intervals.
- It initializes two more state variables
count1andcount2. Both are initially set to 0. These variables will store the values of the two counters. - It uses two
useEffecthooks. They set up intervals to update the counters at specified intervals. - The first
useEffectsets up an interval forcount1to increment every 1 second (1000 milliseconds). It also returns a cleanup function that clears the interval when thisuseEffectis unmounted or when the component is re-rendered. - The second
useEffectdoes the same forcount2, but it increments it every 3 seconds (3000 milliseconds). - The
returnstatement defines the JSX that will be rendered on the web page. It displays the current values ofcount1andcount2.
So expected result is to see something like this:

However, it’s working in this way:

Why it is not working?
The issue with the second counter not updating as expected is due to the lack of specifying a dependency array in the useEffect hooks.
- During the initial render, the component is displayed with both
count1andcount2set to 0. - After the initial render, the
useEffecthooks are executed. - The first counter (
count1) has a shorter interval and updates every 1 second, callingsetCount1. This causes the component to re-render with the new value ofcount1(which is 1) after 1 second. - As a result of the re-render, the cleanup functions of both
useEffecthooks are called, clearing both intervals. - In the next render,
count1has a value of 1, butcount2is still at 0. - The
useEffecthooks run again. - The first counter once again calls
setCount1after 1 second to incrementcount1. This re-renders the component withcount1value of 2. - However, the cleanup functions are called again for both
useEffecthooks, preventing the second counter from updatingcount2.
Conclusion
In React’s useEffect hook, specifying a dependency array is not always required, but it can be crucial for controlling when the effect runs and ensuring that your component behaves as expected or if it is running infinite loop.
