反应错误:目标容器不是DOM元素

lnh*_*ell 51 javascript django dom reactjs

我刚开始使用React,所以这可能是一个非常简单的错误,但我们走了.我的HTML代码非常简单:

<!-- base.html -->
<html>
  <head>
    <title>Note Cards</title>
    <script src="http://fb.me/react-0.11.2.js"></script>
<!--     <script src="http://fb.me/JSXTransformer-0.11.2.js"></script> -->
    <script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static "css/style.css" %}">
    <script src="{% static "build/react.js" %}"></script>
  </head>
  <body>
    <h1 id="content">Note Cards</h1>
    <div class="gotcha"></div>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

请注意,我在这里使用django的加载静态文件.我的javascript有点复杂,所以我不会在这里发布所有内容,除非有人请求它,但错误的行是这样的:

React.renderComponent(
  CardBox({url: "/cards/?format=json", pollInterval: 2000}),
  document.getElementById("content")
);
Run Code Online (Sandbox Code Playgroud)

之后我得到'目标容器不是DOM元素错误'但似乎document.getElementById("content")几乎肯定是一个DOM元素.

我查看了这个 stackoverflow帖子,但它似乎对我的情况没有帮助.

任何人都知道我为什么会收到这个错误?

lnh*_*ell 76

我想到了!

看完这篇博文后,我意识到这条线的位置:

<script src="{% static "build/react.js" %}"></script>
Run Code Online (Sandbox Code Playgroud)

错了.该行必须是该<body>部分中的最后一行,就在</body>标记之前.向下移动线解决了问题.

我对此的解释是,react在<head>标签之间寻找id ,而不是在<body>标签中.因此,它无法找到contentid,因此它不是真正的DOM元素.

  • 或者(也许是一个好主意),是在一个onload/ready监听器中包装`React.render`调用.然后将脚本标记放在何处并不重要,因为节点将存在. (17认同)
  • 您使用“&lt;head&gt;”标签的“我对此的解释”对我来说没有意义。更重要的是,React(js 文件)尝试初始化您的应用程序(具有 React id 的容器),但您的应用程序容器尚未呈现。因此,将 `&lt;script&gt;..` 放在应用程序容器之后应该已经解决了问题,它在我的位置上解决了问题。对于这种情况,最好的做法是将所有 js 资源放在“&lt;/body&gt;”之前。 (2认同)

mik*_*ols 11

只是提供一个替代解决方案,因为它没有被提及。

defer在这里使用 HTML 属性完全没问题。因此,在加载 DOM 时,<script>当 DOM 命中脚本时,将加载常规。但是如果我们使用defer,那么 DOM脚本将并行加载。很酷的事情是脚本最终会被评估 - 当 DOM 加载时()。

<script src="{% static "build/react.js" %}" defer></script>
Run Code Online (Sandbox Code Playgroud)


Pre*_*vic 11

网络包解决方案

如果您在 React 中使用 webpack 和 HMR 时遇到此错误。

您需要创建模板index.html并将其保存在src文件夹中:

<html>
    <body>
       <div id="root"></root>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

现在,当我们有模板时,id="root"我们需要告诉 webpack 生成 index.html 它将镜像我们的index.html文件。

要做到这一点:

plugins: [
    new HtmlWebpackPlugin({
        title: "Application name",
        template: './src/index.html'
    })
],
Run Code Online (Sandbox Code Playgroud)

template属性会告诉 webpack 如何构建index.html文件。


小智 10

对于那些在网站的某些部分实现了 React js 并遇到此问题的人。只需添加一个条件来在渲染反应组件之前检查该元素是否存在于该页面上。

<div id="element"></div>

...

const someElement = document.getElementById("element")
    
if(someElement) {
  ReactDOM.render(<Yourcomponent />, someElement)
}
Run Code Online (Sandbox Code Playgroud)


dan*_*lla 7

此外,将您的移动<script></script>到 html 文件底部的最佳实践也解决了这个问题。


Ali*_*lia 7

还要确保在index.html中设置的id与您在index.js中引用的id相同

index.html:

<body> <div id="root"></div> <script src="/bundle.js"></script> </body>

index.js:

ReactDOM.render(<App/>,document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)


Bin*_*ati 7

我在 React 版本 16 中遇到了同样的错误。当尝试呈现 React 组件的 Javascript 包含在 html 中的静态父 dom 元素之前时,就会出现此错误。修复与接受的答案相同,即只有在 html 中定义了静态父 dom 元素后,才应包含 JavaScript。


A-3*_*312 5

你也可以这样做:

document.addEventListener("DOMContentLoaded", function(event) {
  React.renderComponent(
    CardBox({url: "/cards/?format=json", pollInterval: 2000}),
    document.getElementById("content")
  );
})
Run Code Online (Sandbox Code Playgroud)

DOMContentLoaded事件在初始 HTML 文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载。