I want to understand when React mounts and unmounts a component. The official document on useEffect seems to suggest that cleanup action always run so that we can rely on it to unsubscribe to some API. However, I find that it isn't always the case. In the following toy example, I define clean-up actions for both <About>
and <About2>
, I expect both would unmount first before they are mounted again. As a result, the "mounting" messages should always come after an "unmounting" message (except for the first "mounting" message). This indeed is the case if I switch between these two pages by clicking the <Link>
s. However, if I switch between these two pages by directly editing the browser's url bar, there is no "unmounting" message. That is, the clean-up actions as defined in useEffect
don't run at all in this case. I suspect the reason is being 'page reloading'(by which, I mean react somehow abandons whatever it has and reconstruct everything from scratch). My questions are:
- Does editing browser's url directly always trigger a 'page reloading'?
- How can we make sure the clean-up actions(eg. unsubscribe to an API) still run in case of 'page reloading'. As shown by this example, clean-up action defined in
useEffect
may not always work.
Thank you!
import React, { useEffect } from 'react';
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<div>
<ul>
<li>
<Link to="About"> About</Link>
</li>
<li>
<Link to="About2"> About2</Link>
</li>
</ul>
<hr />
<Routes>
<Route path="/about" element={<About />} />
<Route path="/about2" element={<About2 />} />
</Routes>
</div>
</BrowserRouter>
);
}
function About() {
useEffect(()=>{
console.log("Mounting About");
return ()=>{console.log("Unmounting About");};
},[]);
console.log("In About");
return (
<div>About</div>
);
}
function About2() {
useEffect(()=>{
console.log("Mounting About2");
return ()=>{console.log("Unmounting About2");};
},[]);
console.log("In About2");
return (
<div>About2</div>
);
}