Search code examples
reactjseffect

Does React run effect clean up for already rendered component instances before rendering new component instances?


const MyComp = someValue => (
    useEffect(() => {
         console.log('[1]run effect for instance with value', someValue);

         return () => console.log('[2]do effect clean up for instance with value', someValue);
    }, []);

    return <div />;
);

const MyList = () => {
    const [ showFirstInstance, setValue ] = useState(false);

    return (<div>
      <div onClick={ () => setValue(true) }>Click me</div>
      { showFirstInstance && <MyComp someValue='1' /> } {/* FIRST INSTANCE */ }
      { !showFirstInstance && <MyComp someValue='2' /> } {/* SECOND INSTANCE */ }
    </div>);
};

render(MyList, document.getElementById('root'));

I did empirically test a similar chunk of code (though with context/dispatch instead of state) and the answer to the following question would be 'yes' in the limited case I tested with N instances of the same component where only one is active at the same time.

Will in general React 16.8+ first run the effect clean up [2] for the active instance (<MyComp someValue='2' />) and then run the initialization effect [1] for the newly active instance (<MyComp someValue='1' />), no matter the order of the components in the rendering tree?

By order of the components in the rendering tree I mean: no matter if <MyComp someValue='1' /> and <MyComp someValue='2' /> are swapped in the function, or the initial value for showFirstInstance is true or false. So basically, any rendering order for those instances.


Solution

  • Yes, React does first run effect of cleanup component. The reason is simple, this process has nothing to do with which was first in code, it is related to which component was rendered before, so first the pre state needs to cleanup and then the new state start its rendering.

    It is also stated in offical react document,

    When exactly does React clean up an effect? React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time.