Инвариантное нарушение: registerComponent (...): целевой контейнер не является элементом DOM

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

необнаруженная ошибка: инвариантное нарушение: _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>

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

9 ответов


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

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

и в коде вызова

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

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

хорошая вещь о script внизу - это то, что он не будет блокировать рендеринг до загрузки скрипта, если вы добавите рендеринг сервера React в ваш проект.


/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 bundle до содержимое HTML загружается.

источник: Реактивный Стартовый Комплект, изоморфна стиле-погрузчик


на готовая функция можно использовать так:

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

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

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

просто угадать, как насчет добавления в индекс.HTML-код следующим образом:

type="javascript"

такой:

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

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


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

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

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

2) очень распространенным способом является добавление тега скрипта в нижней части вашего document (после body tag):

<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, который увольняется, когда дом готовы:

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

есть еще больше вариантов, чтобы проверить, если дом готово, но короткий ответ:НЕ запустите любой скрипт, прежде чем убедитесь, что ваш дом готов в каждом случае...

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


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

document.getElementById('root')

to

document.querySelector('root')

обратите внимание на недостающие '#' Это должно было быть

document.querySelector('#root')

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


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


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

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


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