Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning: Can't perform a React state update on an unmounted component. In a functional component

I have a functional component where I get a value from my localStorage and use that value to set a value in a state:

localforage.getItem<string>('sortType').then((value) => {
  setSortType(value)
})

const [sortType, setSortType] = useState('release_date');

When I run the component I get a log:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

I've read that this happens because I'm using a async method localforage.getItem on a state. But I haven't found a solution that would work in a functional component.

like image 514
Peter Boomsma Avatar asked Aug 02 '20 07:08

Peter Boomsma


People also ask

How do you fix can't perform a React state update on an unmounted component This is a no op but it indicates a memory leak in your application?

Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

What is unmounted component in React?

In the unmounting (or deletion, or "cleanup") phase, we have just one lifecycle method to help us out: componentWillUnmount . componentWillUnmount is the last function to be called immediately before the component is removed from the DOM.

How do you force unmount in React?

You can just unmount it conditionally. All you have to do is remove it from the DOM in order to unmount it. As long as renderMyComponent = true , the component will render. If you set renderMyComponent = false , it will unmount from the DOM.

How do you know if a functional component is unmounted?

To check if the React component is unmounted, we can set a state in the callback that's returned in the useEffect hook callback. We create the isMounted state with the useState hook. Then we call the useEffect hook with a callback that calls setIsMounted to set isMounted to true .

Why can't I perform a React state update on an unmounted component?

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application.

Why is my react app not updating state?

This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. at SetStateWarning (http://localhost:3000/static/js/bundle.js:639:80) This warning is pointing out that we can’t perform a React state update on an unmounted component.

Why do I get a warning when unmounting a component?

One thing is certain that somewhere in your code you are using setState or useState hook function even after unmounting the component. The issue is not, why we are getting this warning, else, we need to know how to deal with it properly.

Why am I getting this common State Update warning?

We saw how a simple component with an asynchronous state update may yield this common warning, think about all those components you have with a similar case. Make sure you check if the component is actually mounted before you perform a state update.


2 Answers

You are setting the state after the promise resolves, which can cause this code to run after the component has unmounted.

To resolve this, you can check if the component is still mounted before setting the state:

const isMountedRef = useRef(true)
useEffect(() => () => { isMountedRef.current = false }, [])

Since the dependency array is empty the effect is called when the component mounts, and the callback is executed when it dismounts

// somewhere in your code later
localforage.getItem<string>('sortType').then((value) => {
  if (isMountedRef.current) {
      setSortType(value)
  }
})
like image 164
thedude Avatar answered Sep 21 '22 13:09

thedude


Try to run the sortType from localStorage once by using React.useEffect as below:

const [sortType, setSortType] = useState('release_date');

React.useEffect(() => {
  localforage.getItem<string>('sortType').then((value) => {
    setSortType(value)
  })
}, []);
like image 43
Ali Torki Avatar answered Sep 19 '22 13:09

Ali Torki