Posted on under React by Owen Conti.
When you attempt to update the state of a component after its been unmounted, React will warn you that you should not do that.
This can happen if you perform an asynchronous side effect (such as loading data) and then unmount the component before the asynchronous function is finished.
When using React's
useEffect
hook, you can keep track of whether the component is mounted and then conditionally update state. This happens within the
useEffect
body:
1React.useEffect(() => { 2 let unmounted = false; 3 setTimeout(() => { 4 if (!unmounted) { 5 // update state here... 6 } 7 }, 3000); 8 9 return () => {10 unmounted = true;11 };12});
The function we return at the bottom of
useEffect
is called whenever the component is unmounted. This allow us to track a boolean
unmounted
to determine if we should update state when our asynchronous function finishes.
Check out the full example below:
1import React from "react"; 2import ReactDOM from "react-dom"; 3 4function App() { 5 const [showPage, togglePage] = React.useState(true); 6 7 return ( 8 <div> 9 {showPage ? <Page /> : null}10 <button onClick={() => togglePage(!showPage)}>11 Toggle Page component12 </button>13 </div>14 );15}16 17function Page() {18 const [data, setData] = React.useState(null);19 20 React.useEffect(() => {21 let unmounted = false;22 console.log("Running effect to fetch data");23 24 setTimeout(() => {25 console.log("Data loaded for page");26 27 if (!unmounted) {28 setData("Some data you loaded from a server somewhere...");29 }30 }, 3000);31 32 return () => {33 unmounted = true;34 };35 }, []);36 37 return (38 <div>39 <div>Data: {data}</div>40 </div>41 );42}43 44const rootElement = document.getElementById("root");45ReactDOM.render(<App />, rootElement);
Hopefully you found this article useful! If you did, share it on X!
Found an issue with the article? Submit your edits against the repository.