111

I just got started using React, so this is probably a very simple mistake, but here we go. My html code is very simple:

<!-- base.html -->
<html>
  <head>
    <title>Note Cards</title>
    <script src="http://<url>/react-0.11.2.js"></script>
<!--     <script src="http://<url>/JSXTransformer-0.11.2.js"></script> -->
    <script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static "css/style.css" %}">
    <script src="{% static "build/react.js" %}"></script>
  </head>
  <body>
    <h1 id="content">Note Cards</h1>
    <div class="gotcha"></div>
  </body>
</html>

Note that I am using Django's load static files here. (My JavaScript is a bit more complex, so I won't post it all here unless someone requests it.) This is the line with the error:

React.renderComponent(
  CardBox({url: "/cards/?format=json", pollInterval: 2000}),
  document.getElementById("content")
);

After which I get the 'target container is not a DOM element error' yet it seems that document.getElementById("content") is almost certainly a DOM element.

I looked at this stackoverflow post, but it didn't seem to help in my situation.

Anyone have any idea why I'd be getting that error?

Super Jade
  • 5,609
  • 7
  • 39
  • 61
lnhubbell
  • 3,304
  • 5
  • 17
  • 22
  • 1
    Anyone who's stuck with Meteor Tutorial with this error? Here's the solution https://stackoverflow.com/a/51007095/4777670 – Saif Jul 03 '18 at 08:03

12 Answers12

125

I figured it out!

After reading this blog post I realized that the placement of this line:

<script src="{% static "build/react.js" %}"></script>

was wrong. That line needs to be the last line in the <body> section, right before the </body> tag. Moving the line down solves the problem.

My explanation for this is that react was looking for the id in between the <head> tags, instead of in the <body> tags. Because of this it couldn't find the content id, and thus it wasn't a real DOM element.

Mahesh Pawar
  • 153
  • 1
  • 14
lnhubbell
  • 3,304
  • 5
  • 17
  • 22
  • 22
    Alternatively (and probably a good idea), is to wrap the `React.render` call in an onload/ready listener. Then it won't matter where you put the script tag as the node will exist. – Paul O'Shannessy Oct 18 '14 at 18:22
  • @PaulO'Shannessy Ahhh that makes sense! I'll do that as well. – lnhubbell Oct 22 '14 at 18:35
  • 2
    Your "My explanation for this" with the `` tags does not makes sense for me. Its more so that React (js file) tried to initialize your app (container with the react id), but your app container was not rendered yet. So putting the ` – fabpico Jul 24 '18 at 11:27
58

Also make sure id set in index.html is same as the one you referring to in index.js

index.html:

<body> 
    <div id="root"></div>
    <script src="/bundle.js"></script>
</body>

index.js:

ReactDOM.render(<App/>,document.getElementById('root'));
Ghasem
  • 14,455
  • 21
  • 138
  • 171
Alia Anis
  • 1,355
  • 11
  • 7
23

webpack solution

If you got this error while working in React with webpack and HMR.

You need to create template index.html and save it in src folder:

<html>
    <body>
       <div id="root"></div>
    </body>
</html>

Now when we have template with id="root" we need to tell webpack to generate index.html which will mirror our index.html file.

To do that:

plugins: [
    new HtmlWebpackPlugin({
        title: "Application name",
        template: './src/index.html'
    })
],

template property will tell webpack how to build index.html file.

Kesha Antonov
  • 349
  • 5
  • 14
Predrag Davidovic
  • 1,411
  • 1
  • 17
  • 20
  • Why do I need to do this? Is there some background magic with templates or is this because you expect them to generate a random UI.hash filename? – Chris3y Jul 24 '22 at 00:12
13

Just to give an alternative solution, because it isn't mentioned.

It's perfectly fine to use the HTML attribute defer here. So when loading the DOM, a regular <script> will load when the DOM hits the script. But if we use defer, then the DOM and the script will load in parallel. The cool thing is the script gets evaluated in the end - when the DOM has loaded (source).

<script src="{% static "build/react.js" %}" defer></script>
mikemols
  • 824
  • 10
  • 17
10

Also, the best practice of moving your <script></script> to the bottom of the html file fixes this too.

daniella
  • 403
  • 7
  • 17
10

For those that implemented react js in some part of the website and encounter this issue. Just add a condition to check if the element exist on that page before you render the react component.

<div id="element"></div>

...

const someElement = document.getElementById("element")
    
if(someElement) {
  ReactDOM.render(<Yourcomponent />, someElement)
}
alfieindesigns
  • 109
  • 1
  • 3
  • This can be the case with a Drupal behavior when they are called multiple times and the `context` variable does not include the root element. – daniels Dec 02 '21 at 14:09
8

I had encountered the same error with React version 16. This error comes when the Javascript that tries to render the React component is included before the static parent dom element in the html. Fix is same as the accepted answer, i.e. the JavaScript should get included only after the static parent dom element has been defined in the html.

Binita Bharati
  • 5,239
  • 1
  • 43
  • 24
5

Also you can do something like that:

document.addEventListener("DOMContentLoaded", function(event) {
  React.renderComponent(
    CardBox({url: "/cards/?format=json", pollInterval: 2000}),
    document.getElementById("content")
  );
})

The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

user2226755
  • 12,494
  • 5
  • 50
  • 73
3

One of the case I encountered the same error in a simple project. I hope the solution helps someone.

Below code snippets are sufficient to understand the solution :

index.html

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>

someFile.js : Notice the line const portalElement = document.getElementById("overlays"); below :

const portalElement = document.getElementById("overlays");

const Modal = (props) => {
  return (
    <Fragment>
            {ReactDOM.createPortal(<Backdrop />, portalElement)}
            
      {ReactDOM.createPortal(
        <ModalOverlay>{props.children}</ModalOverlay>,
        portalElement
      )}
          
    </Fragment>
  );
};

I didn't have any element with id = "overlays" in my index.html file, so the highlighted line above was outputting null and so React wasn't able to find inside which element it should create the portal i.e {ReactDOM.createPortal(<Backdrop />, portalElement)} so I got below error

enter image description here

I added the div in index.html file and the error was gone.

 <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="overlays"></div>
    <div id="root"></div>
  </body>
utkarsh-k
  • 836
  • 8
  • 17
2

I got the same error i created the app with create-react-app but in /public/index.html also added matrialize script but there was to connection with "root" so i added

<div id="root"></div>

just before

<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/ materialize.min.js"></script>

And it worked for me .

  • This was my problem. I accidentally deleted root from the index.html. Re-adding solved the problem. – ibrahim Jan 11 '21 at 23:27
0

Target container is not a DOM element.

I achieved this error with a simple starter app also.

// index.js

ReactDOM.render(
  <Router>
      <App />,
  document.getElementById('root')
  </Router>
);

Solution:

Syntax errors can cause this error. I checked my syntax and wrapped my <App /> properly.

ReactDOM.render(
  <Router>
      <App />
  </Router>,
  document.getElementById('root')
);
Super Jade
  • 5,609
  • 7
  • 39
  • 61
0

In my case, I forget to add this line to the index.js file

document.getElementById('root')

and I forget to import react-dom import ReactDOM from 'react-dom'; so you can use ReactDOM later in the same file

Hope this will be helpful for you