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.
1 Answer
Reset to default 2If 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]);
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744586441a4582340.html
评论列表(0条)