I get error, but CHANGELOG says:
v0.5.0 - Tue, 22 Sep 2015 19:19:44 GMT
[changed] setAppElement method is now optional.
So I'm confused.
Error: react-modal: You must set an element with Modal.setAppElement(el) to make this accessible
at validateElement (index.js:224)
at show (index.js:211)
at Object.toggle (index.js:219)
Same problem here
Hello,
Same problem here.
The whole problem is the scripts being loaded at the top of the page. react-modal was trying to set the app element to document.body, while it doesn't exist yet. If you did the same, within your code, it resulted as the same as your script was probably loaded before the DOM too.
I solved it by calling it in the lifecycle method componentWillMount:
componentDidMount() {
Modal.setAppElement('body');
},
I can create a pull request solving this issue if you wish to?
Updated 05/11/18: Use componentDidMount as componentWillMount is flagged as deprecated.
woah, what? that should not be optional, that's the whole point of this library.
Thank you @yachaka for that snippet, solved my issue. I ran into this when running tests, fwiw.
@ryanflorence The doc is precising that by default react-modal is anchored to document.body, which would be fine:
/*
By default the modal is anchored to document.body. All of the following overrides are available.
* element
Modal.setAppElement(appElement);
* query selector - uses the first element found if you pass in a class.
Modal.setAppElement('#your-app-element');
*/
I guess the doc/or the code has to change?
I only got this error when we switched to using webpack-dev-server. Very weird.
Update: injecting the bundled application JS into <body> instead of <head> seems to have solved it for me for now, but I think ideally react-modal should wait until the DOM is loaded to try attaching to document.body (if that's what's going on).
The appElement is only used in one place: https://github.com/reactjs/react-modal/blob/master/lib/components/Modal.js#L75, and isn't documented at all. I think that line should be using the closed over appElement variable instead. The fact that you can set the app element in two different ways, and they are both used seems wrong.
This happened for me when moving to webpack. It was working fine before. I don't understand it but adding the componentWillMount snippet fixed it for me as well.
I'm having this too.
yachaka's advice doesn't work because on server-side there's no document.
ungoldman's advice does work — moving javascript to <body/> tag makes the error go away, but this is a bug, and it should wait for the DOM content to load.
I got this problem too, like ungoldman, when we started building/running with webpack. No one's advice was helping. We have a 'common' project, which had the code that was using react-modal, and was deployed to the main app project. I had to move the modal code to the main app project to get it to work.
Depending on when it evaluates [email protected]:/lib/helpers/ariaAppHider.js#L1:
document.body does not exist yet and it will resolve to undefined || null. Modal.setAppElement() is called with null or not called at all with the <script /> placed on <head /> (same as above).selector that does not match any results.If you don't want to depend on setAppElement(), @ungoldman answer is correct .
@yachaka snippet prevents this behavior by defining the element before placing the <Modal />.
If rendering on server-side, @halt-hammerzeit is correct and you must provide a document.body, before requiring the modal script (perhaps it should be preferable to use setAppElement() in this case).
Too late to help, but I hope new users can understand what is going on if they face this issue.
I started getting this error/warning yesterday after upgrading my react-modal and react libs to the latest versions. To make the error/warning go away, I modified my main .jsx file to include an explicit call to Modal.setAppElement( ) like this:
// Weird-- we get warnings in the console if we don't explicitly set the Modal appElement...
Modal.setAppElement('body');
ReactDOM.render(myAppBody, document.getElementById('index-main-div'));
And yes, my Javascript is a child of the HTML body, as suggested by @ungoldman...
<html>
...
...
<body>
<div id="index-main-div"></div>
<script src="./js/myapp.js"></script>
</body>
</html>
<ReactModal
appElement={document.getElementById('app')}
...
FYI This also works.
@damorton Not, it doesn't.
There's no document on the server.
document && document.getElementById('#app') && ReactModal.setAppElement('#app');
Is the following possible with react-modal, if the modal is used within a component only, can it be mounted such that the overlay covers only that component - and not parent / grandparents of that component ? I tried it, it didn't seem to work, it went back to covering the whole screen.
componentWillMount() is flagged UNSAFE in v16.3+ and will be deprecated in v17. componentDidMount() does the trick for me.
What have you done when testing single child component? Then root App is not included.
Most helpful comment
Hello,
Same problem here.
The whole problem is the scripts being loaded at the top of the page.
react-modalwas trying to set the app element todocument.body, while it doesn't exist yet. If you did the same, within your code, it resulted as the same as your script was probably loaded before the DOM too.I solved it by calling it in the lifecycle method
componentWillMount:I can create a pull request solving this issue if you wish to?
Updated 05/11/18: Use
componentDidMountascomponentWillMountis flagged as deprecated.