Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invariant Violation: _registerComponent(...): Target container is not a DOM element

I get this error after a making trivial React example page:

Uncaught Error: Invariant Violation: _registerComponent(...): Target container is not a DOM element.

Here's my code:

/** @jsx React.DOM */ 'use strict';  var React = require('react');  var App = React.createClass({   render() {     return <h1>Yo</h1>;   } });  React.renderComponent(<App />, document.body); 

HTML:

<html> <head>   <script src="/bundle.js"></script> </head> <body> </body> </html> 

What does this mean?

like image 408
Dan Abramov Avatar asked Oct 25 '14 19:10

Dan Abramov


People also ask

How do I fix target container is not a DOM element?

To solve the "createRoot(...): Target container is not a DOM element" error, make sure that the ID you are using to select the element is the same ID that you have specified in your index. html file and place the react script below the code that declares the div element.

Why is ReactDOM undefined?

This issue could pop out because: you don't have module react-dom properly installed inside your project and you tried to call it, or simply you didn't call this module correctly. Notes : – The name you use to import should be exactly the same as the name when you use it.

How do you define ReactDOM?

ReactDOM is a package that provides DOM specific methods that can be used at the top level of a web app to enable an efficient way of managing DOM elements of the web page. ReactDOM provides the developers with an API containing the following methods and a few more. render() findDOMNode()


2 Answers

By the time script is executed, document element is not available yet, because script itself is in the head. While it's a valid solution to keep script in head and render on DOMContentLoaded event, it's even better to put your script at the very bottom of the body and render root component to a div before it like this:

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

and in the bundle.js, call:

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

You should always render to a nested div instead of body. Otherwise, all sorts of third-party code (Google Font Loader, browser plugins, whatever) can modify the body DOM node when React doesn't expect it, and cause weird errors that are very hard to trace and debug. Read more about this issue.

The nice thing about putting script at the bottom is that it won't block rendering until script load in case you add React server rendering to your project.


Update: (October 07, 2015 | v0.14)

React.render is deprecated, use ReactDOM.render instead.

Example:

import ReactDOM from 'react-dom';  ReactDOM.render(<App />, document.getElementById('root')); 
like image 155
Dan Abramov Avatar answered Sep 30 '22 03:09

Dan Abramov


/index.html

<!doctype html> <html>   <head>     <title>My Application</title>     <!-- load application bundle asynchronously -->     <script async src="/app.js"></script>     <style type="text/css">       /* pre-rendered critical path CSS (see isomorphic-style-loader) */     </style>   </head>   <body>     <div id="app">       <!-- pre-rendered markup of your JavaScript app (see isomorphic apps) -->     </div>   </body> </html> 

/app.js

import React from 'react'; import ReactDOM from 'react-dom'; import App from './components/App';  function run() {   ReactDOM.render(<App />, document.getElementById('app')); }  const loadedStates = ['complete', 'loaded', 'interactive'];  if (loadedStates.includes(document.readyState) && document.body) {   run(); } else {   window.addEventListener('DOMContentLoaded', run, false); } 

(IE9+)

Note: Having <script async src="..."></script> in the header ensures that the browser will start downloading JavaScript bundle before HTML content is loaded.

Source: React Starter Kit, isomorphic-style-loader

like image 40
Konstantin Tarkus Avatar answered Sep 30 '22 01:09

Konstantin Tarkus