Я получаю эту ошибку после создания тривиальной страницы примера 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>
Что это значит?
К моменту выполнения скрипта элемент document
еще не доступен, поскольку сам script
находится в head
. Хотя это правильное решение для сохранения script
в head
и рендеринга по событию DOMContentLoaded
, еще лучше поместить ваш script
в самый DOMContentLoaded
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 в свой проект.
React.render
устарел, вместо этого используйтеReactDOM.render
.
Пример:
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
/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.
ReactDOM.render
вместо React.render
.
defer
может быть лучшим вариантом
функция готовности может быть использована следующим образом:
$(document).ready(function () {
React.render(<App />, document.body);
});
Если вы не хотите использовать jQuery, вы можете использовать функцию onload
:
<body onload="initReact()">...</body>
DOMContentLoaded
будет более подходящим даже для обработки, чем для load
(это то, что использует jQuery ). Вы также можете сделать это в JS с помощью window.addEventListener
, без необходимости использования встроенных обработчиков и глобальных функций.
просто дикая догадка, как насчет добавления в index.html следующего:
type="javascript"
вот так:
<script type="javascript" src="public/bundle.js"> </script>
Для меня это сработало!: -)
type="text/javascript"
работал правильно.
Я столкнулся с той же ошибкой. Это оказалось вызвано простой опечаткой после изменения моего кода с:
document.getElementById('root')
в
document.querySelector('root')
Обратите внимание на пропущенный '#' Это должно было быть
document.querySelector('#root')
Просто публикация на случай, если это поможет кому-либо еще решить эту ошибку.
Да, в основном то , что вы сделали, правильно, за исключением того, что вы забыли, что 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, прежде чем делать это...
Я столкнулся с похожим/тем же сообщением об ошибке. В моем случае у меня не было целевой DOM node, который должен отображать компонент ReactJS. Убедитесь, что цель HTML node четко определена с помощью соответствующего "id" или "name", а также других атрибутов HTML (подходящих для вашего дизайна)
В моем случае эта ошибка была вызвана горячей перезагрузкой при введении новых классов. На этом этапе проекта используйте обычные наблюдатели для компиляции кода.
использовать эти src dom в файле index.html, а затем связать с файлом js
Для тех, кто использует ReactJS.Net и получает эту ошибку после публикации:
Проверьте свойства ваших .jsx файлов и убедитесь, что для параметра Build Action
установлено значение Content
. Те, которые установлены в None
, не будут опубликованы. Я пришел к этому решению из этого SO-ответа.