admin管理员组

文章数量:1391964

In a video I saw creating a progress bar and updated its value using state and wrapped it inside setInterval for updating it every 15 millisecond and the whole being wrapped inside useEffect, with no dependency. As state change triggers a UI update, the component re-renders and state value changes, consoling the value should print from 3000 till 0 (or in short in descending order) but it only prints 3000 (200 times) why?

const [progressBar, setProgressBar] = useState(3000);

useEffect(() => {
  const progress = setInterval(() => {
    console.log(progressBar);
    setProgressBar((prevVal) => prevVal - 15);
  }, 15);

  return () => clearInterval(progress);
}, []);

If there is no dependency means the contents inside useEffect should be executed only once know? Kindly explain.

In a video I saw creating a progress bar and updated its value using state and wrapped it inside setInterval for updating it every 15 millisecond and the whole being wrapped inside useEffect, with no dependency. As state change triggers a UI update, the component re-renders and state value changes, consoling the value should print from 3000 till 0 (or in short in descending order) but it only prints 3000 (200 times) why?

const [progressBar, setProgressBar] = useState(3000);

useEffect(() => {
  const progress = setInterval(() => {
    console.log(progressBar);
    setProgressBar((prevVal) => prevVal - 15);
  }, 15);

  return () => clearInterval(progress);
}, []);

If there is no dependency means the contents inside useEffect should be executed only once know? Kindly explain.

Share Improve this question edited Mar 16 at 20:48 Spectric 32.4k6 gold badges29 silver badges54 bronze badges asked Mar 16 at 20:43 ABISHEK NSABISHEK NS 511 silver badge7 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

If there is no dependency means the contents inside useEffect should be executed only once know?

Yes, the effect ran once and instantiated a callback function that is called on an interval with a set Javascript Closure.

The interval is why the callback is called repeatedly, and the closure is why you see the same progressBar value each time. The reason the setProgressBar call works is because it is working from a separate closure that is passed the current state value, e.g. the callback passed to setProgressBar.

If you would like to see the state update you can use a separate effect with a dependency on the state value that is updating.

const [progressBar, setProgressBar] = useState(3000);

// Run once to instantiate interval callback to enqueue state updates
useEffect(() => {
  const progress = setInterval(() => {
    setProgressBar((prevVal) => prevVal - 15);
  }, 15);

  return () => clearInterval(progress);
}, []);

// Run each time `progressBar` state updates
useEffect(() => {
  console.log(progressBar);
}, [progressBar]);

本文标签: