I've a button in the UI and in OnClick event handler, I've to run a set Interval timer.In Set Interval timer I'm checking for a condition and if the condition is met I'm updating the state,But It is not working properly.
import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
function Counter() {
let [count, setCount] = useState(0);
let [gg, setgg] = useState(false);
function countdownTimer() {
console.log(count + gg.toString());
if (count > 10) {
setgg(true);
}
setCount((count) => count + 1);
}
function handleClick() {
let id = setInterval(countdownTimer, 1000);
}
return (
<div>
<button onClick={handleClick}>Click</button>
<h1>{count + gg.toString()}</h1>
</div>
);
}
const rootElement = document.getElementById("root");
// Second interval to demonstrate the issue.
// Fast updates from it cause the Counter's
// interval to constantly reset and never fire.
setInterval(() => {
ReactDOM.render(<Counter />, rootElement);
}, 1
00);
In the countdownTimer function there is a console.log which is always printing "0 false" but the componenet in UI is updating to the correct number.
Could you please let me know why
code sand box link: https://codesandbox.io/s/dank-grass-7o4ms?file=/src/index.js
screenshot of Component updating correctly but the console.log is always zero.
- the count is always '0' in the console.log
Stale count
state enclosed in updfun
callback.
- if count is always zero how does the state get updated corretct eveytime?
You used a functional state update so each update correctly updates from the previous state, not the state from when the callback was enqueued.
- how can I print the correct value of count in the console.log() in the countdowntimer function.
Use an useEffect
to issue a side-effect of logging state when it updates, and to also check the count
greater than 10
to set gg
state.
function Counter() {
const [count, setCount] = useState(0);
const [count, setCount] = useState(0);
const [gg, setgg] = useState(false);
useEffect(() => {
console.log(count + gg.toString());
if (count > 10) {
setgg(true);
}
}, [count, gg]);
useEffect(() => () => clearInterval(timerRef.current), []);
function updfun() {
setCount((count) => count + 1);
}
function handleClick() {
timerRef.current = setInterval(updfun, 1000);
}
return (
<div>
<button onClick={handleClick}>Click</button>
<h1>{count + gg.toString()}</h1>
</div>
);
}