Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media tries to update unmounted component #139

Open
jonask94 opened this issue Nov 12, 2019 · 22 comments
Open

Media tries to update unmounted component #139

jonask94 opened this issue Nov 12, 2019 · 22 comments

Comments

@jonask94
Copy link

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

@edorivai
Copy link
Collaborator

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

@jonask94
Copy link
Author

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.

@edorivai
Copy link
Collaborator

Thanks, I'll have to look into this.

stevenwcarter added a commit to stevenwcarter/react-media that referenced this issue Nov 21, 2019
Issue ReactTraining#139 was the same issue I was having when resizing a window.
I was receiving an error about a possible memory leak since setState
was called on an unmounted component. It seems like the `getMatches`
call was taking just long enough that the component could be unmounted
while it was executing. By using a `_mounted` flag, we can determine
if it is safe to call `setState` and bypass it if the component is
unmounted. I looked at using an abort signal, but I don't think the
`matchMedia` API is robust enough for that currently.
stevenwcarter added a commit to stevenwcarter/react-media that referenced this issue Nov 21, 2019
I suspected that the issue lay in the listener being created in the
constructor, and playing havoc with the `this` scope so I broke it out
into its own function and passed the necessary parameters in. This
succeeded in resolving the issue reported in ReactTraining#139 by removing the root
of the issue instead of covering it up with my previous PR.
@geegog
Copy link

geegog commented Dec 6, 2019

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.

@makker
Copy link

makker commented Jan 16, 2020

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.

@mmbrtstd
Copy link

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

@adriankiezik
Copy link

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.

@zjhch123
Copy link

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.

@edorivai
Copy link
Collaborator

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

@zjhch123
Copy link

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

@zjhch123
Copy link

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.

@GuichiZhao
Copy link

The error still present when using useMedia

@jhimelymendoza
Copy link

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"

@edorivai
Copy link
Collaborator

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

@jonkan
Copy link

jonkan commented Oct 20, 2020

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

@clieee
Copy link

clieee commented Oct 20, 2020

Same here

@edorivai
Copy link
Collaborator

@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. 🙏

@jonkan
Copy link

jonkan commented Oct 21, 2020

@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.

@Hainesy
Copy link

Hainesy commented Feb 10, 2021

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.

@djucy
Copy link

djucy commented Jul 30, 2022

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

@vinaysruban
Copy link

vinaysruban commented Oct 3, 2022

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.

@CalvinJamesHeath
Copy link

The issue still persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests