Javascript 不变违规:_registerComponent(...):目标容器不是 DOM 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26566317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Invariant Violation: _registerComponent(...): Target container is not a DOM element
提问by Dan Abramov
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?
这是什么意思?
回答by Dan Abramov
By the time script is executed, documentelement is not available yet, because scriptitself is in the head. While it's a valid solution to keep scriptin headand render on DOMContentLoadedevent, it's even better to put your scriptat the very bottom of the bodyandrender root component to a divbefore it like this:
到脚本执行时,document元素还不可用,因为script它本身在head. 虽然这是一个有效的解决方案,以保持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 divinstead of body.Otherwise, all sorts of third-party code (Google Font Loader, browser plugins, whatever) can modify the bodyDOM node when React doesn't expect it, and cause weird errors that are very hard to trace and debug. Read more about this issue.
您应该始终呈现为嵌套div而不是body. 否则,各种第三方代码(Google Font Loader、浏览器插件等等)都可以body在 React 不期望的时候修改DOM 节点,并导致难以追踪和调试的奇怪错误。阅读有关此问题的更多信息。
The nice thing about putting scriptat 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.renderis deprecated, useReactDOM.renderinstead.
React.render已弃用,请ReactDOM.render改用。
Example:
例子:
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
回答by Konstantin Tarkus
/index.html
/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
/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 beforeHTML content is loaded.
注意:包含<script async src="..."></script>在标题中可确保浏览器在加载 HTML 内容之前开始下载 JavaScript 包。
Source: React Starter Kit, isomorphic-style-loader
来源:React Starter Kit,isomorphic-style-loader
回答by nils petersohn
the ready functioncan be used like this:
该准备功能,可以使用这样的:
$(document).ready(function () {
React.render(<App />, document.body);
});
If you don't want to use jQuery, you can use the onloadfunction:
如果不想使用 jQuery,可以使用以下onload函数:
<body onload="initReact()">...</body>
回答by taquiles
just a wild guess, how about adding to index.html the following:
只是一个疯狂的猜测,如何在 index.html 中添加以下内容:
type="javascript"
like this:
像这样:
<script type="javascript" src="public/bundle.js"> </script>
For me it worked! :-)
对我来说它奏效了!:-)
回答by mangakid
I ran into the same error. It turned out to be caused by a simple typo after changing my code from:
我遇到了同样的错误。原来是由一个简单的错字在更改我的代码后引起的:
document.getElementById('root')
to
到
document.querySelector('root')
Notice the missing '#' It should have been
注意缺少的“#”它应该是
document.querySelector('#root')
Just posting in case it helps anyone else solve this error.
只是发布以防它帮助其他人解决此错误。
回答by Alireza
Yes,basically what you done is right, except you forget that JavaScript is sync in many cases, so you running the code before your DOMgets loaded, there are few ways to solve this:
是的,基本上你做的都是对的,除了你忘记了 JavaScript 在很多情况下是同步的,所以你在DOM加载之前运行代码,有几种方法可以解决这个问题:
1) Check to see if DOMfully loaded, then do whatever you want, you can listen to DOMContentLoadedfor example:
1)检查DOM是否完全加载,然后做你想做的,你可以听DOMContentLoaded例如:
<script>
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});
</script>
2) Very common way is adding the script tag to the bottom of your document(after body tag):
2)非常常见的方法是将脚本标签添加到您的底部document(在 body 标签之后):
<html>
<head>
</head>
<body>
</body>
<script src="/bundle.js"></script>
</html>
3) Using window.onload, which gets fired when the entire page loaded(img, etc)
3) 使用window.onload,在整个页面加载时触发(img 等)
window.addEventListener("load", function() {
console.log("Everything is loaded");
});
4) Using document.onload, which gets fired when the DOMis ready:
4) Using document.onload,当DOM准备好时它会被触发:
document.addEventListener("load", function() {
console.log("DOM is ready");
});
There are even more options to check if DOMis ready, but the short answer is DO NOTrun any script before you make sure your DOM is readyin every cases...
还有更多选项可以检查DOM是否准备就绪,但简短的回答是在确保DOM在每种情况下都准备就绪之前不要运行任何脚本......
JavaScript is working along with DOMelements and if they are not available, will return null, could break the whole application... so always make sure you are fully ready to run your JavaScript before you do...
JavaScript 正在与DOM元素一起工作,如果它们不可用,将返回null,可能会破坏整个应用程序......所以在你做之前总是确保你完全准备好运行你的 JavaScript......
回答by ghazaleh javaheri
If you use webpack for rendering your react and use HtmlWebpackPlugin in your react,this plugin builds its blank index.html by itself and injects js file in it,so it does not contain div element,as HtmlWebpackPlugin docs you can build your own index.html and give its address to this plugin, in my webpack.config.js
如果你使用 webpack 来渲染你的 react 并在你的 react 中使用 HtmlWebpackPlugin,这个插件会自己构建它的空白 index.html 并在其中注入 js 文件,所以它不包含 div 元素,作为 HtmlWebpackPlugin docs 你可以构建自己的索引。 html 并在我的 webpack.config.js 中为这个插件提供它的地址
plugins: [
new HtmlWebpackPlugin({
title: 'dev',
template: 'dist/index.html'
})
],
and this is my index.html file
这是我的 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>
回答by Micros
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.
在我的例子中,这个错误是由热重载引起的,同时引入了新类。在项目的那个阶段,使用普通的观察者来编译你的代码。
回答by Jecoms
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 Actionis set to Content. Those set to Nonewill not be published. I came upon this solution from this SO answer.
检查 .jsx 文件的属性并确保Build Action设置为Content. 那些设置为None将不会发布。我从这个 SO answer 中找到了这个解决方案。
回答by anie codeskol
I ran into similar/same error message. In my case, I did not have the target DOM node which is to render the ReactJS component defined. Ensure the HTML target node is well defined with appropriate "id" or "name", along with other HTML attributes (suitable for your design need)
我遇到了类似/相同的错误消息。就我而言,我没有定义用于呈现 ReactJS 组件的目标 DOM 节点。确保使用适当的“id”或“name”以及其他 HTML 属性(适合您的设计需要)很好地定义了 HTML 目标节点

