react-modal: Error: You must set an element with `Modal.setAppElement(el)` to make this accessible

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)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 19 (2 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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

componentWillMount() is flagged UNSAFE in v16.3+ and will be deprecated in v17. componentDidMount() does the trick for me.

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>

@damorton Not, it doesn’t. There’s no document on the server.

Depending on when it evaluates react-modal@1.6.5:/lib/helpers/ariaAppHider.js#L1:

  • document.body does not exist yet and it will resolve to undefined || null.
  • if Modal.setAppElement() is called with null or not called at all with the <script /> placed on <head /> (same as above).
  • Probably it can also happen if called with a selector that does not match any results.

browser rendering

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

server-side

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 only got this error when we switched to using webpack-dev-server. Very weird.

document && document.getElementById('#app') && ReactModal.setAppElement('#app');

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.

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.