How to fix "cannot update unmounted component" warning with React hooks. | Owen Conti

How to fix "cannot update unmounted component" warning with React hooks.

Published on Apr 05, 2019 in category React.

๐Ÿ‘‹There's a video version of this post at the bottom of the page.

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:

React.useEffect(() => {
  let unmounted = false;
  setTimeout(() => {
    if (!unmounted) {
      // update state here...
    }
  }, 3000);

  return () => {
    unmounted = true;
  };
});

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:

import React from "react";
import ReactDOM from "react-dom";

function App() {
  const [showPage, togglePage] = React.useState(true);

  return (
    <div>
      {showPage ? <Page /> : null}
      <button onClick={() => togglePage(!showPage)}>
        Toggle Page component
      </button>
    </div>
  );
}

function Page() {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    let unmounted = false;
    console.log("Running effect to fetch data");

    setTimeout(() => {
      console.log("Data loaded for page");

      if (!unmounted) {
        setData("Some data you loaded from a server somewhere...");
      }
    }, 3000);

    return () => {
      unmounted = true;
    };
  }, []);

  return (
    <div>
      <div>Data: {data}</div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);


Thanks for reading!

๐Ÿ‘‹ Hi there! I hope you enjoyed this post. If you did, follow me on Twitter, @owenconti, for updates on new posts.

If you prefer to receive updates via email, subscribe to my newsletter where I send a weekly summary of the content I've released.

Feel free to check out other posts in the React category.