简体   繁体   中英

Why my React component is still updating state even if I do cleanup in useEffect()?

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?

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]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM