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
modal-open not being removed from body after closing modal #1323
Comments
+1, I just ran into this today. Any update? |
Yes I came across this issue. Had to downgrade. The issue is that It might be that its async with the animation so maybe try turning the fade off. Or in your close function just change Basically the modal count is always 1 (never 0 and thus never closes) |
I see. Maybe I'll have time to do a PR this weekend for that. Here's hoping. |
With react strict mode turned on class is almost never removed in development mode as strict mode may invoke constructor twice. |
BTW, it looks like this issue should be fixed by PR #1495 which was just merged. |
FYI, v8.0.1 was just released. It contains #1495 which should solve this problem. Closing. |
I am using reactstrap with typescript. I am using v8.0.1, still I am facing the issue. |
I checked with updated version 8.0.1. The issue still there. It is something due to very quick update in its isOpen prop. I am using Modal in my Loader component. My Loaded component show/hide quickly. |
This issue is still happening for me too, when my component's constructor initialises I fixed it by initialising my own component's state to being false in the constructor, then setting it to true in |
I'm still having this issue on v. ^8.2.0, does somebody have a workaround? For now I'm going to remove the modal-open class by force using: document.body.classList.remove('modal-open'); |
Still having this issue too |
@justingrant please reopen |
@z1m1n This issue has been resolved. If you are experiencing a similar issue, please open a new issues and reference this issue. Please also provide a working minimal code sample which shows the issue (you can use https://stackblitz.com/edit/reactstrap-v8?file=Example.js as a place to start) Also note that this was more properly fixed in the latest release (8.4.0). Please ensure you are using the latest version. Checkout this commit and commit comment: 310b061 |
8.4.1 the issue is still here. I don't know how to reproduce. It happened after I recently upgraded. The project is big and several months old. |
@saysmaster I also had this problem with project ~2 years old, beginning with reactstrap v8.3.0 the classname After hours of debugging and reviewing the reactstrap code and changes introduced between 8.2.0 and 8.4.1 I found the cause - it's because of changes introduced with 310b061. However, from my understanding, it's not a bug in the reactstrap but it's the consequence of wrong usage of the Modal component. Description of what was hapenning in my code:
TLDR description:Modal is forced to unmount, Solution:
|
This bug existed before 310b061 was created so it's not possible for 310b061 to introduce it. I believe there are multiple factors in play. Both cases are race conditions which makes them difficult to reproduce and difficult to determine there was more than one scenario. The difference between state and props is that state is async, leading to issues when the modal unmounts before the state has been updated to reflect the value of the prop which is what 310b061 aimed to fix. With props, the cleanup code run synchronously which means the cleanup happens before other code runs which would unmount the component. But based on your finding, I believe the issue lies with how Currently, here are the possibilities during unmount:
Based on that truth table, maybe we can just check if either |
@TheSharpieOne nice overview, looks good to me. The check if |
Fixed my problem for moment... import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Modal } from "reactstrap";
import 'normalize.css/normalize.css';
import 'alertifyjs/build/css/alertify.min.css';
import 'alertifyjs/build/css/themes/bootstrap.min.css';
import store from '@/redux/store';
import fetchInitialData from '@/redux/fetchInitialData';
import Root from './screens/Root';
import '@/components/PdfViewer/pdfJsPageChange';
/** import Playground from '@/playground'; */
// store.subscribe(() => console.log(store.getState()));
fetchInitialData();
/** Hotfix css-modal */
Modal.prototype.componentWillUnmount = function() {
if (this.props.onExit) {
this.props.onExit();
}
if (this._element) {
this.destroy();
if (this.props.isOpen || this.state.isOpen) {
this.close();
}
}
this._isMounted = false;
};
/** Hotfix css-modal */
ReactDOM.render(
<Provider store={store}>
<Root />
</Provider>
, document.getElementById('ROOT')
); |
This was still an issue for me when I implemented a loading modal in a Solution: I added an effect in my modal to forcefully remove the
|
@AKhoo the fix is merged in master but not released yet @TheSharpieOne is there any ETA for the release? |
Is there any ETA for the release? I expected a patch release already since the last release was months ago... |
The modal-open class remains on the body tag even after the modal is closed. This is an issue of the reactstrap library (reactstrap/reactstrap#1323) which is already fixed buy not released yet. Added a temporary work-around to remove the modal-open class when modal is closed. Closes #426
The modal-open class remains on the body tag even after the modal is closed. This is an issue of the reactstrap library (reactstrap/reactstrap#1323) which is already fixed buy not released yet. Added a temporary work-around to remove the modal-open class when modal is closed. Closes #426
The modal-open class remains on the body tag even after the modal is closed. This is an issue of the reactstrap library (reactstrap/reactstrap#1323) which is already fixed buy not released yet. Added a temporary work-around to remove the modal-open class when modal is closed. Closes #426
I was able to resolve this issue with the following CSS:
My issue was the class being removed but the CSS somehow staying. So, when the modal is not open I'm forcing it to allow scrolling, otherwise the modal's css will apply. |
Modal
#6.5.0
es
#6.6.3
#4.1.3
What is happening?
The
modal-open
CSS class is not being removed from<body>
when I close a modal. Clicking on the header's "x" button (or any other means of closing the modal) causes the page to be unscrollable.What should be happening?
The
modal-open
style should be removed from the page when all modals are closed.Investigation
Tracing through the
Modal
code in Chrome devtools, what I saw was twoModal
instances being constructed but only oneModal
instance is actually being used. The firstModal
instance is being constructed by React but is never used after the constructor runs. It's being thrown away. None of its lifecycle methods are run. The secondModal
instance is being used normally and its lifecycle methods fire, but when it closes,Modal.openCount
is still nonzero so themodal-open
style is not removed from the<body>
.Looking at
Modal.js
code, I saw a problem which explained the behavior above. The Modal constructor contains a side effect: a call toinit()
which setsmodal-open
on the<body>
. The constructor (and henceinit()
) is being called twice, butdestroy()
is only being called once.I was able to resolve the problem by forking reactstrap and moving the call to
init()
from the end of the constructor to the beginning ofcomponentDidMount
:React advises against side effects in constructors. I suspect the behavior above may be one reason for this recommendation. Apparently, React can construct instances and throw them away without running any lifecycle methods!
I'm happy to prepare a PR to move Modal initialization into
componentDidMount()
. But there may be other reasons that I'm not aware of to use this non-recommended side effect in the constructor.Does anyone know the history of why
init()
is being called in the constructor instead of incomponentDidMount
where side effects and DOM manipulations are recommended?Steps to reproduce issue
Repro steps are difficult at the moment because the problem shows up in the middle of a fairly complicated project. To display a modal, my app pushes data into an array that's stored in React Context (the new 16.x kind, not the deprecated old context). Another part of the app will notice the change to Context and will transform each element in the array into one or more modals. When a modal is closed, the onClosed event handler will remove the data from the array in Context which will cause the modal to be unmounted.
I can pull this logic out of my app to provide a simpler repro, but doing this will take some time so (per discussion above) I wanted to understand more about the reasons for initializing in the constructor before going through the trouble of creating a repro. Hope this is OK.
Error message in console
Code
See above-- this behavior is deeply nested inside my app, so it's non-trivial to pull it out. I can do it if needed, though.
The text was updated successfully, but these errors were encountered: