Reputation: 66
I've got a little problem there and I dont know why my solution is not working properly. Here is the code:
const [progress, setProgress] = useState(0);
useEffect(() => {
let isMounted = true;
if(isMounted === true) {
progress < 100 && setTimeout(() => setProgress(progress + 1), 20);
}
return () => isMounted = false;
}, [progress]);
Im doing there setTimeout async operation. Every 20ms i want to set state of progress by 1. Thats all. Also I added isMounted
variable which contains state of component.
The problem is that when lets say, I mount this component and I unmount this immediately after 1s maybe two then i dont get this error. If I wait longer and unmount the component (before setTimeout has time to change the progress state to 100, which is the limit) then this error appears.
Why this error is appearing in such weird way?
Why does this error even appear when the component has clearly communicated when it is mounted and when not?
Upvotes: 1
Views: 56
Reputation: 16576
You need to either clear the timeout in the cleanup or use your isMounted
variable within the timeout itself.
Clearing the timeout:
useEffect(() => {
let timeout;
if (progress < 100) {
timeout = setTimeout(() => {
setProgress(progress + 1)
}, 20);
}
return () => { clearTimeout(timeout) };
}, [progress]);
Using the isMounted
variable:
useEffect(() => {
let isMounted = true;
if (progress < 100) {
setTimeout(() => {
if (isMounted) setProgress(progress + 1);
}, 20)
}
return () => { isMounted = false };
}, [progress]);
Upvotes: 2