ReactTraining / react-media

CSS media queries for React

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Media tries to update unmounted component

jonask94 opened this issue · comments

I’m getting the following warning from a Media-Component which implements a min-width media query:
„Can't perform a React state update on an unmounted component“.

The warning is thrown when the component is already unmounted and the user resizes the window.
It seems as if the event-listener which updates the matches-state is still alive after unmounting.

When inspecting the code I wondered why the initialize-function of Media.js is called two times (1. in constructor, 2. in componentDidMount). Doesn’t this behaviour ends up in eventListeners that will never be removed since in componentWillUnmount only the listeners created in the second call of initialize will be eleminiated?

I’m currently using react-media in version 1.10.0

Thanks for the report. It would be really helpful if you could create a reproducible Codesandbox.
Two quick questions:

  • We've had a similar report a while ago: #100. Are you experiencing the same as in that issue?
  • Which browser are you using? #100 turned out to be Safari specific.

Here is a little codepen: https://codepen.io/jonask94/pen/jOOveEJ
(in the initial situation everything is fine; after pressing the button and unmounting the media component the warning is thrown when resizing the window)
It seems as if #100 relates to it, but I tested it on chrome and firefox so it is not safari specific.

Thanks, I'll have to look into this.

I have the same issue.

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 the componentWillUnmount method. in Media (at Contact.js:176) in Contact (created by Context.Consumer)

If I navigate to the page with the Media component and navigate away to another page then change the view to say mobile or table (in browser inspect), I get the error above.

I got this warning in my app using "react-media" 1.10.0. App uses React 16.9.

Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the Media component.

I'm not sure what I did before the warning fired. Sorry :/
And can't reproduce it anymore either.

I'm getting this bug as well working with NextJS. You can reproduce it easily with a default installation of NextJS.

Also getting this error:

Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Media component.

I'm not using state at my component, so I think I can ignore this error.

I think the root cause is the method initialize, which is called in the constructor and the componentDidMount.

In constructor, it calls the initialize, the this.queries will be an array with some listeners. And then the component is mounted and trigger the componentDidMount, which causes the this.queries be covered by another new array without canceling the old listeners.

I'd like to fix it but I saw that someone has a PR to refactor the whole component to the functional component, and in that PR he use the useEffect to make sure every time the listeners will be canceled.

Let's wait for his PR to be merged.

PR has been merged, it's available at react-media@next. Please let me know if you get the time to test, thanks! 🙏

I can't repro it with the version @next. The issue should be resolved 😊

Hey one thing needs to be pointed out.

This issue will happen again if you are in the development mode using the React.StrictMode to render the <App />. The root cause is the React needs to detect unexpected side effects, and it will call the useMedia twice using the different contexts.

I don't think it is a blocking issue since it only happens in the dev env, let's keep investigation.

The error still present when using useMedia

The error still persists, I have version 1.10.0 installed and I still get. The PR already approved? When would this problem be solved?

index.js:1 Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Media component.

"react": "^16.13.1",
"react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1",
"react-flexbox-grid": "^2.1.2",
"react-intl": "^5.8.4",
"react-media": "^1.10.0",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
"styled-components": "^5.2.0",
"typescript": "^3.8.2"

@jhimelymendoza can you try npm install react-media@next?

@edorivai I'm seeing the same issue using react-media@next (react-media@^2.0.0-rc.1) :/

Same here

@jonkan @clieee @jhimelymendoza could you guys confirm whether you're seeing this with useMedia and/or <Media>?

Would also be helpful if y'all could post browser and react-media versions. 🙏

@edorivai I'm seeing it with useMedia having react-media-2.0.0-rc.1 in Chrome 86.0, Safari 14.0 and Firefox 82.0.

I'm seeing it with <Media> on Chrome 88.0. Easily reproducible when resizing the window. If it helps, I'm redirecting routes when switching from desktop to mobile.

Hello, I've gotten error in Chrome 103.0:

"react_devtools_backend.js:4026 Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Media component.".

I don't use state in this component

I'm also experiencing the error on Chrome.

"Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Media component."

This is in <React.StrictMode> though.

The issue still persists.