1

Consider the code snippet below:

import { useEffect } from "react";

export const Hello = () => {
  useEffect(() => {
    console.log("Mounted");
    return () => {
      console.log("Unmounted");
    };
  }, []);

  return <h1>Hello</h1>;
};

I'm observing that every time I make some changes and save, I get the Unmounted and Mounted log printed, which means that the component is getting unmounted and then mounted back.

This is not something critical, but in my project I'm working with Iframes and on unmount I run some code that I don't want to run unnecessarily.

Was this the case from the start, did something change?

2 Answers2

1

When using hot module reloading, changing something inside a functional component and saving will not result in the component being unmounted and mounted again but all effects re-run.

Source: Comment from Dan Abramov, author of React Hot Loader

This is the case for functional components in general. As stated in the React documentation on useEffect:

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.

Houssam
  • 1,848
  • 1
  • 4
  • 24
  • Sorry I didn't fully get you. I'm talking specifically about Hot Module Reloading, this has nothing to do with state change or React in general, it is specific to how Create React App works. –  Oct 18 '21 at 16:41
  • Yes, my answer is specifically about hot module reloading, but since that wasn't mentioned in your question I added the second statement to make it clear that the behavior is different from how components re-render during updates. Hot module reloading results in destroying the react context and creating a new one, thus components are unmounted and mounted again. – Houssam Oct 18 '21 at 16:44
  • So, you say this was always the case and this is how Create React App has been working? –  Oct 18 '21 at 16:44
  • I don't know why but I thought that this wasn't the case so far, unmounting wasn't happening. Let's wait for some other responses. Maybe I'm getting confused with something else –  Oct 18 '21 at 16:46
  • It seems like I was not entirely correct, Create React App 4+ uses React Refresh, and according to [this comment](https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/85#issuecomment-626188070), functional components are not remounted but effects are re-executed. I could not find any other source confirming this information though. – Houssam Oct 18 '21 at 16:58
  • Yes, the comment I linked seems like a reliable information. My initial answer only applied to class components, I thought it applied to functional components as well and I was wrong about that. – Houssam Oct 18 '21 at 17:10
0

This wasn't always the case, CRA earlier used "React Hot Loader" but with version 4 it upgraded to "React Fast Refresh".

Fast Refresh introduces the concept of reusable state. With fast refresh every time you save a file, your effects would re-run but the state of the components are preserved.

Note: You should ensure that your components are resilient to being "mounted" and "unmounted" more than once and React 18's strict mode even ensures this resilience by "unmounting" & "re-mounting" newly mounted components, read more here.

Som Shekhar Mukherjee
  • 4,701
  • 1
  • 12
  • 28