Search code examples
reactjsreact-hooksuse-effect

useEffect in child component pattern


I have the following two components.

<Foo>
  <Bars/>
<Foo>

When Foo is called the console shows:

call Bar useEffect
Warning: Cant perform a React state update on an unmounted component...
call Foo useEffect
call Bar useEffect again

Here's the codepen but it doesn't generate the same warning which could be because its in development mode on my local. It does show null prints though.

https://codepen.io/rsgmon/pen/OJmPGpa

Is this component structure, with useEffect in each component, not recommended/allowed?
If it's ok what do I need to change to avoid the warning?


Solution

  • This is likely occurring because a state update to Foo triggers a re-render, causing Bars to unmount and remount.

    Then the original Bars API request completes and it attempts to update state on the component that isn't mounted anymore, hence the warning.

    You can fix it by declaring a variable inside the effect that's initially false and setting it to true in the effect's cleanup function:

    useEffect(() => {
      let unmounted = false;
      
      doSomeAsynchronousStuff()
        .then( result => {
    
          if (unmounted) {
            return; // not mounted anymore. bail.
          }
    
          // do stuff with result
    
        })
    
      return () => unmounted = true; // cleanup gets called on un-mount
    }, [])