本文翻译自:Invariant Violation: _registerComponent(…): Target container is not a DOM element
I get this error after a making trivial React example page: 在制作了简单的React示例页面后,我收到此错误:
Uncaught Error: Invariant Violation: _registerComponent(...): Target container is not a DOM element. 未捕获错误:不变违规:_registerComponent(...):目标容器不是DOM元素。
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:
<html>
<head>
<script src="/bundle.js"></script>
</head>
<body>
</body>
</html>
What does this mean? 这是什么意思?
#1楼
参考:https://stackoom.com/question/1nT6z/不变违规-registerComponent-目标容器不是DOM元素
#2楼
By the time script is executed, document
element is not available yet, because script
itself is in the head
. 到脚本执行时, document
元素还不可用,因为script
本身就在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: 虽然这是一个有效的解决方案,以保持script
的head
和渲染上DOMContentLoaded
事件 ,它甚至不如把你的script
在最底部body
和渲染根组件的div
之前是这样的:
<html>
<head>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
and in the bundle.js
, call: 并在bundle.js
,调用:
React.render(<App />, document.getElementById('root'));
You should always render to a nested div
instead of body
. 您应该始终渲染到嵌套的div
而不是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. 否则,各种第三方代码(谷歌字体加载器,浏览器插件,等等)可以在React不期望它时修改body
DOM节点,并导致非常难以跟踪和调试的奇怪错误。 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. 将script
置于底部的好处是,在脚本加载之前,如果您将React服务器渲染添加到项目中,它将不会阻止呈现。
Update: (October 07, 2015 | v0.14 ) 更新:(2015年10月7日| v0.14 )
React.render
is deprecated, useReactDOM.render
instead.React.render
已过时,使用ReactDOM.render
代替。
Example: 例:
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
#3楼
the ready function can be used like this: 就绪功能可以像这样使用:
$(document).ready(function () {
React.render(<App />, document.body);
});
If you don't want to use jQuery, you can use the onload
function: 如果您不想使用jQuery,可以使用onload
函数:
<body onload="initReact()">...</body>
#4楼
/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+) (IE9 +)
Note : Having <script async src="..."></script>
in the header ensures that the browser will start downloading JavaScript bundle before HTML content is loaded. 注意 :在标头中包含<script async src="..."></script>
可确保浏览器在加载HTML内容之前开始下载JavaScript包。
Source: React Starter Kit , isomorphic-style-loader 来源: React Starter Kit , isomorphic-style-loader
#5楼
In my case this error was caused by hot reloading, while introducing new classes. 在我的情况下,这个错误是由热重新加载引起的,同时引入了新的类。 In that stage of the project, use normal watchers to compile your code. 在项目的该阶段,使用普通观察者来编译代码。
#6楼
For those using ReactJS.Net and getting this error after a publish: 对于那些使用ReactJS.Net并在发布后收到此错误的人:
Check the properties of your .jsx files and make sure Build Action
is set to Content
. 检查.jsx文件的属性,并确保将Build Action
设置为Content
。 Those set to None
will not be published. 设置为None
那些将不会发布。 I came upon this solution from this SO answer . 我从这个SO答案中找到了这个解决方案。