在制作了简单的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
render on DOMContentLoaded
event,更好的是把你的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
。否则,当React不期望它时,各种第三方代码(Google Font Loader,浏览器插件,等等)都可以修改body
DOM节点,并导致非常难以跟踪和调试的奇怪错误。 Read more about this issue.
将script
放在底部的好处是,在脚本加载之前它不会阻止渲染,以防你将React服务器渲染添加到项目中。
React.render
已弃用,请改用ReactDOM.render
。
例:
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
对于那些使用ReactJS.Net并在发布后收到此错误的人:
检查.jsx文件的属性,并确保Build Action
设置为Content
。那些设置为None
的内容将不会发布。我从this SO answer那里得到了这个解决方案。
在index.html文件中使用这些src dom而不是与js文件链接
/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);
}
(S + +)
注意:在标题中包含<script async src="..."></script>
可确保浏览器在加载HTML内容之前开始下载JavaScript包。
ready function可以像这样使用:
$(document).ready(function () {
React.render(<App />, document.body);
});
如果您不想使用jQuery,可以使用onload
函数:
<body onload="initReact()">...</body>
只是一个疯狂的猜测,如何添加到index.html以下:
type="javascript"
像这样:
<script type="javascript" src="public/bundle.js"> </script>
对我来说它有效! :-)
我遇到了同样的错误。事实证明,在更改我的代码之后,这是由一个简单的拼写引起的:
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)非常常见的方法是将脚本标记添加到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之前...
如果你使用webpack渲染你的反应,并在你的反应中使用HtmlWebpackPlugin,这个插件自己的空白index.html并在其中注入js文件,因此它不包含div元素,因为HtmlWebpackPlugin docs你可以构建自己的index.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>
在我的情况下,这个错误是由热重新加载引起的,同时引入了新的类。在项目的该阶段,使用普通观察者来编译代码。
我遇到了类似/相同的错误消息。在我的例子中,我没有目标DOM节点来渲染定义的ReactJS组件。确保HTML目标节点使用适当的“id”或“name”以及其他HTML属性(适合您的设计需求)定义良好