React cleanup function doesn't clean state

react usecallback
react useeffect
react hooks
can't perform a react state update on an unmounted component
react-hooks/exhaustive-deps
react, ( usestate)
react hooks componentwillunmount
useeffect(async)

experts, please explain me, why in the following code the state of the property won't be cleaned in the useEffect cleanup function?

My component:

export default function TestComp() {

  let { id } = useParams();
  const [value, setValue] = useState(null);
  console.log('[TestComp] called...');

  const cleanup = () => {
    console.log('[TestComp] old value', value);
    setValue(null);
  };

  useEffect(() => {
    console.log('[TestComp] id changed: ', id);
    console.log('[TestComp] value in useEffect', value);
    setValue(id);
    return () => {
      cleanup();
    }
  }, [id]);

  return (<React.Fragment>Test id: {id}</React.Fragment>)
}

Console output:

[TestComp] called... TestComp.js:8
[TestComp] old value satellites:MTP TestComp.js:11
[TestComp] id changed:  satellites:MTP TestComp.js:16
[TestComp] value in useEffect satellites:FPGA TestComp.js:17
[TestComp] called... 2 TestComp.js:8
[TestComp] old value satellites:FPGA TestComp.js:11
[TestComp] id changed:  satellites:FNE TestComp.js:16
[TestComp] value in useEffect satellites:MTP TestComp.js:17
[TestComp] called... TestComp.js:8

I expect that, when useEffect will be called for the 2. time, the value wull be cleaned up and is null, but it still keeps the old value:

value in useEffect satellites:MTP TestComp.js:17

Thank you in advance.

React cleanup function doesn't clean state, Return function from useEffect just cleans up the previous effects before applying the next effects. But main problem in your code is The way the timing works, an effect function will only fire after the browser is done with layout and paint – too late, if you wanted to make a visual change. For those cases, React provides the useMutationEffect and useLayoutEffect hooks, which work the same as useEffect aside from when they are fired.

You might want to add another useEffect, because, in the current situation, the cleanup function will run only on unmount which is pretty useless for the current logic.

export default function TestComp() {
  let { id } = useParams();
  const [value, setValue] = useState(null);
  console.log('[TestComp] called...');

  useEffect(() => {
    console.log('[TestComp] id changed: ', id);
    console.log('[TestComp] value in useEffect', value);
    setValue(id);

    /* v Useless cleanup because the component unmounts anyway,
         the `value` state will be cleaned automatically.
    return () => {
      cleanup();
    }
    */
  }, [id]);

  // ^ Firstly, the `value` changed on id change
  // v Secondly, the `value` will be reset on `value` change
  useEffect(() => {
    console.log('[TestComp] old value', value);
    setValue(null);
  }, [value]);

  return <>Test id: {id}</>;
}

Clean Up Async Requests in `useEffect` Hooks - DEV, Tagged with react, hooks, webdev. If your hook does something async, in most cases they should be cleaned up properly to avoid any unwanted side-effects. If you are using fetch , then abort your requests in the clean up� It goes back to what we saw earlier. The useEffect and the "cleanup" function always pointing to cleanups from different updates. The "cleanup" is always one behind, so there is not a way for them to communicate with each other. But wait, there is a way. Dan’s solution! Pass a function to the useState updater. As a bonus, there is one more

I think it's a matter of the sequence in which things happen.

useEffect will 'capture' value as part of a closure when it is called, i.e. when the TestComp function is called. When id changes React will schedule a call to the cleanup function and then a call to the effect. However TestComp is not called again until after the new effect function has been called.

You can see this in the log as each old value from the cleanup function is immediately followed by id changed from the effect function.

And because the new effect functions 'captures' value from when TestComp was called, it will not see the value set by the cleanup function.

Also note, at least from testing I saw React complain about value and cleanup not being in the dependencies for useEffect.

React useEffect cleanup: How and when to use it, Cleanup function in the useEffect hook. The useEffect hook is built in a way that if we return a function within the method, this function will execute� React gives us a way to do this with useEffect. When passing a function to useEffect, if that function also returns a function, that returned function will be called to perform any needed cleanup. We can put our removeEventListener code there:

Clean up request in useEffect React Hook, To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. The message is not very clear and it does not give you� I've put together for you an entire visual cheatsheet of all of the concepts and skills you need to master React in 2020. Each part is designed to be immensely helpful by showing you real-world, practical examples with meaningful comments to guide you along the way.

How the useEffect Hook Works (with Examples), Well, the cleanup function you can (optionally) return from useEffect isn't React does not do this – it will only re-render in response to state� The function passed to useEffect will run after the render is committed to the screen. Think of effects as an escape hatch from React’s purely functional world into the imperative world. By default, effects run after every completed render, but you can choose to fire them only when certain values have changed. Cleaning up an effect

React Hooks — (useState and useEffect-useRef with clean-ups), question; Hooks are functions that let us “hook into” React state and lifecycle features from stateless functional(won't anymore!) components. Since the React 16.8 update which added hooks to function components, you might have seen function components replacing class components everywhere. Partly this is just because developers suffer from 'shiny-object-syndrome', and hooks are new and shiny, but there are also good reasons for the shift as well.

Comments
  • It will cleanup your state when your component is unmounted.Basically If you want to implement componentWillUnmount. than you have to return in useEffect. For more reference see this article : daveceddia.com/useeffect-hook-examples
  • Try moving the log to another useEffect with value as dependency