useState + setTimeout = broken state setter
shadowvzs opened this issue · 3 comments
const SubTest = () => {
const [s, setS] = useState(10);
setTimeout(() => {
const newValue = Math.random();
console.log('----', newValue)
setS(s => newValue);
}, 1000);
return (
<h3> Count: {s} </h3>
);
}
const Test = (): JSX.Element => {
const [s, setS] = useState(10);
setTimeout(() => {
const newValue = Math.random();
console.log(newValue)
setS(s => newValue);
}, 2000);
return (
<div>
<h1>
Count: {s} {s1}
</h1>
<SubTest />
<SubTest />
</div>
);
}
// ---------------------
const MainCmp = (props: any) => {
return (
<div>{Test()}</div>
);
}
const element = <MainCmp />;
const container = document.getElementById("root")
render(element, container!)
-
Main (broken): the setter in Test component not change the state value (s, it is always 10), refresh the component but the value remain the initial.
-
Secondary (sometimes broken after 1st change): counter in SubTest sometimes work, sometimes break after first value change.
no console error, the newValue is correct, component is rerun each time just the state saving issue
somehow always a new hook created which not conneted with the dom and never deleted the old one so at end browser with freeze after 15-30 sec
Hey. It isn't a good idea to call setTimeout
inside the render function.
Remember that render is called many times, and for each render you are creating 3 timeouts, and each timeout creates 3 more every time it's fired, so you end up with timeouts growing exponentially, and that will freeze your browser.
Hey. It isn't a good idea to call
setTimeout
inside the render function.
Remember that render is called many times, and for each render you are creating 3 timeouts, and each timeout creates 3 more every time it's fired, so you end up with timeouts growing exponentially, and that will freeze your browser.
so this is the expected behaviour? well i thought i was able to use setTimeout in react but maybe it was not in render, just in in handler
yes, it's the same on React: only use setTimeout inside of an effect or event handler.