Инвариантное нарушение: _registerComponent (...): контейнер-объект не является элементом DOM

Я получаю эту ошибку после создания тривиальной страницы примера React:

Непринятая ошибка: инвариантное нарушение: _registerComponent (...): контейнер-объект не является элементом DOM.

Здесь мой код:

/** @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>

Что это значит?

Ответ 1

Ко времени выполнения сценария элемент document еще не доступен, поскольку сам script находится в head. Хотя это правильное решение для сохранения script в head и рендеринга на событии DOMContentLoaded, еще лучше поместить ваш script в самый низ body и Отобразить корневой компонент в div до того, как он выглядит так:

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

и в bundle.js позвоните:

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

Вы всегда должны выполнять рендеринг на вложенный div вместо body. В противном случае всевозможные сторонние коды (Google Font Loader, плагины для браузера и т.д.) могут изменить узел DOM body, когда React не ожидает этого и вызывает странные ошибки, которые очень сложно отследить и отладить. Подробнее об этой проблеме.

Хорошая вещь о размещении script в нижней части состоит в том, что он не будет блокировать рендеринг до загрузки скрипта, если вы добавите рендеринг сервера React в свой проект.


Обновление: (07 октября 2015 г. | v0.14)

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

Пример:

import ReactDOM from 'react-dom';

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

Ответ 2

/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 +)

Примечание: наличие <script async src="..."></script> в заголовке гарантирует, что браузер начнет загружать пакет JavaScript до загрузки содержимого HTML.

Источник: React Starter Kit, isomorphic-style-loader

Ответ 3

функция готовности может быть использована следующим образом:

$(document).ready(function () {
  React.render(<App />, document.body);
});

Если вы не хотите использовать jQuery, вы можете использовать функцию onload:

<body onload="initReact()">...</body>

Ответ 4

просто дикая догадка, как насчет добавления в index.html следующего:

type="javascript"

вот так:

<script type="javascript" src="public/bundle.js"> </script>

Для меня это сработало!: -)

Ответ 5

Да, в основном то , что вы сделали, правильно, за исключением того, что вы забыли, что JavaScript во многих случаях синхронизирован, поэтому вы запускаете код до загрузки DOM, и есть несколько способов решить эту проблему:

1) Проверьте, полностью ли загружен DOM, затем делайте что хотите, вы можете прослушать DOMContentLoaded, например:

<script>
  document.addEventListener("DOMContentLoaded", function(event) {
    console.log("DOM fully loaded and parsed");
  });
</script>

2) Очень распространенный способ - добавить тег script внизу document (после тега body):

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

3) Использование window.onload, которое запускается при загрузке всей страницы (img и т.д.)

window.addEventListener("load", function() {
  console.log("Everything is loaded");
});

4) Использование document.onload, который запускается, когда DOM готов:

document.addEventListener("load", function() {
  console.log("DOM is ready");
});

Есть еще больше опций, чтобы проверить, готов ли DOM, но краткий ответ - НЕ запускайте скрипт, пока вы не убедитесь, что ваш DOM готов во всех случаях...

JavaScript работает вместе с элементами DOM и, если они недоступны, вернет значение null, может привести к поломке всего приложения... поэтому всегда убедитесь, что вы полностью готовы к запуску JavaScript, прежде чем делать это...

Ответ 6

Я столкнулся с той же ошибкой. Это оказалось вызвано простой опечаткой после изменения моего кода с:

document.getElementById('root')

в

document.querySelector('root')

Обратите внимание на пропущенный '#' Это должно было быть

document.querySelector('#root')

Просто публикация на случай, если это поможет кому-либо еще решить эту ошибку.

Ответ 7

Если вы используете webpack для рендеринга вашего реакции и используете HtmlWebpackPlugin в своем реакции, этот плагин создает свой пустой index.html сам по себе и внедряет в него js файл, поэтому он не содержит элемента div, так как HtmlWebpackPlugin docs вы можете создать свой собственный индекс. HTML и дать свой адрес этому плагину, в моем webpack.config.js

plugins: [            
    new HtmlWebpackPlugin({
        title: 'dev',
        template: 'dist/index.html'
    })
],

а это мой файл index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="shortcut icon" href="">
    <meta name="viewport" content="width=device-width">
    <title>Epos report</title>
</head>
<body>
   <div id="app"></div>
   <script src="./bundle.js"></script>
</body>
</html>

Ответ 8

В моем случае эта ошибка была вызвана горячей перезагрузкой при введении новых классов. На этом этапе проекта используйте обычные наблюдатели для компиляции кода.

Ответ 9

Я столкнулся с похожим/тем же сообщением об ошибке. В моем случае у меня не было целевой DOM node, который должен отображать компонент ReactJS. Убедитесь, что цель HTML node четко определена с помощью соответствующего "id" или "name", а также других атрибутов HTML (подходящих для вашего дизайна)

Ответ 10

Для тех, кто использует ReactJS.Net и получает эту ошибку после публикации:

Проверьте свойства ваших .jsx файлов и убедитесь, что для параметра Build Action установлено значение Content. Те, которые установлены в None, не будут опубликованы. Я пришел к этому решению из этого SO-ответа.

Ответ 11

использовать эти src dom в файле index.html, а затем связать с файлом js

Ответ 12

Легко просто сделать базовый HTML CSS js и отобразить скрипт из js

mport React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

var destination = document.querySelector('#container');

   ReactDOM.render(
<div>
<p> hello world</p>
</div>, destination


	); 
body{

    text-align: center;
    background-color: aqua;
  padding: 50px;
  border-color: aqua;
  font-family: sans-serif;
}
#container{
  display: flex;
  justify-content: flex;

}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
   
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />   
    <title> app  </title>
  </head>
  <body>
 

    <div id="container">
      
    </div>

  </body>
</html>