不变违规:_registerComponent(...):目标容器不是DOM元素

时间:2014-10-25 19:22:50

标签: javascript dom reactjs

我在制作了一个简单的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>

这是什么意思?

14 个答案:

答案 0 :(得分:586)

到执行脚本时,document元素尚不可用,因为script本身位于head。尽管将script放在headrender 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否则,各种第三方代码(Google Font Loader,浏览器插件等等)都可以当React不期望它时修改body DOM节点,并导致非常难以跟踪和调试的奇怪错误。 Read more about this issue.

script置于底部的好处是,在脚本加载之前,如果您将React服务器渲染添加到项目中,它将不会阻止渲染。


更新:(2015年10月7日| v0.14

  不推荐使用

React.render,请使用ReactDOM.render   代替。

示例:

import ReactDOM from 'react-dom';

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

答案 1 :(得分:52)

/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>可确保浏览器在加载 HTML内容之前开始下载JavaScript包

来源:React Starter Kitisomorphic-style-loader

答案 2 :(得分:16)

ready function可以像这样使用:

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

如果您不想使用jQuery,可以使用onload函数:

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

答案 3 :(得分:9)

只是一个疯狂的猜测,如何向index.html添加以下内容:

type="javascript"
像这样:

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

对我而言,它有效! : - )

答案 4 :(得分:4)

是的,基本上你所做的是正确的,除了你忘了JavaScript在很多情况下是同步的,所以你在 DOM 加载之前运行代码,有解决这个问题的几种方法:

1)检查 DOM 是否已满载,然后执行任何操作,您可以收听 DOMContentLoaded ,例如:

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

2)非常常见的方法是将脚本标记添加到document的底部(在正文标记之后):

<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 ......

答案 5 :(得分:4)

我遇到了同样的错误。事实证明,在更改我的代码之后,这是由一个简单的拼写引起的:

document.getElementById('root')

document.querySelector('root')

注意缺少的#&#39;#&#39; 应该是

document.querySelector('#root')

只是发布,以防其他人帮助解决此错误。

答案 6 :(得分:1)

在我的情况下,这个错误是由热重新加载引起的,同时引入了新类。在项目的该阶段,使用普通观察者来编译代码。

答案 7 :(得分:1)

我遇到了类似/相同的错误消息。在我的例子中,我没有目标DOM节点来渲染定义的ReactJS组件。确保HTML目标节点使用适当的“id”或“name”以及其他HTML属性(适合您的设计需求)定义良好

答案 8 :(得分:1)

如果您使用Webpack来呈现您的React并在Hact中使用HtmlWebpackPlugin,则此插件本身会自行填充空白index.html并在其中注入js文件,因此它不包含div元素,因为HtmlWebpackPlugin文档可以构建您自己的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>

答案 9 :(得分:1)

当您得到:

错误:未捕获的错误:目标容器不是DOM元素。

您可以使用DOMContentLoaded事件或将<script ...></script>标签移动到身体底部。

DOMContentLoaded 事件在完全加载并解析了初始HTML文档时触发,而无需等待样式表,图像和子帧完成加载。

document.addEventListener("DOMContentLoaded", function(event) {
  ReactDOM.render(<App />, document.getElementById('root'));
})

答案 10 :(得分:0)

对于那些使用ReactJS.Net并在发布后收到此错误的人:

检查.jsx文件的属性,并确保Build Action设置为Content。那些设置为None的内容将不会发布。我从this SO answer找到了这个解决方案。

答案 11 :(得分:0)

在index.html文件中使用这些src dom,然后与js文件链接

答案 12 :(得分:0)

简单地制作基本的HTML CSS js并从js渲染脚本

mport React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

var destination = document.querySelector('#container');

   ReactDOM.render(
<div>
<p> hello world</p>
</div>, destination


	); 
body{

    text-align: center;
    background-color: aqua;
  padding: 50px;
  border-color: aqua;
  font-family: sans-serif;
}
#container{
  display: flex;
  justify-content: flex;

}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
   
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />   
    <title> app  </title>
  </head>
  <body>
 

    <div id="container">
      
    </div>

  </body>
</html>

答案 13 :(得分:0)

在我使用 jQuery 的情况下 - 出于某种原因,window.onload 的行为与 jQuery 的 onload 不同

所以这个对我有用:

<script>
    $(function () {          <= replacing window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        ...

      window.ui = ui;
    });
  </script>