不変の違反:_registerComponent(…):ターゲットコンテナーはDOM要素ではありません


388

取るに足らない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>

これは何を意味するのでしょうか?


8
@ go-oleg:これはES6の短い表記です。react-toolsにはES6トランスパイラーが搭載されているため、問題はありません。ここを参照してください
ダン・アブラモフ

14
私はこの同じエラーに遭遇しました、そして他の人が示唆したように、それはあなたのbundle.jsファイルがあまりに早くロードされているためです。このエラーを解決するには、<script>タグを本文に(終了</ body>タグの前の最後の行として)移動します。
Todd R

2
それはここでは役に立ちません
daslicht

@daslichtあなたがあなたの答えを見つけたことを願っていますが、そう言われています:クラスとIDを混同していないことをダブルチェックしてください。document.getElementById( "foo")が<div class = "foo">を読み取るタグを見つけることは決してありません
Dave Kanter

回答:


626

スクリプトが実行されるときには、それ自体がにあるdocumentため、要素はまだ使用できません。それは維持するために有効な解決策ですが中と上にレンダリングイベント、それがためにも、良いでしょうあなたを置くの一番下にしてまでのルートコンポーネントをレンダリングし、このようにそれの前に:scriptheadscriptheadDOMContentLoadedscriptbody 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フォントローダー、ブラウザープラグインなど)がbodyDOMノードを変更し、Reactが予期しない場合にDOMノードを変更して、トレースやデバッグが非常に困難な奇妙なエラーを引き起こす可能性があります。この問題の詳細をご覧ください。

script一番下に置くことの良い点は、プロジェクトにReactサーバーレンダリングを追加した場合に備えて、スクリプトが読み込まれるまでレンダリングをブロックしないことです。


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

React.render廃止予定ですReactDOM.render 。代わりに使用してください。

例:

import ReactDOM from 'react-dom';

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

3
webpackでimportステートメントを使用していますが、まだこのエラーが発生します。スクリプトをロードする順序はwebpackが処理すると思いましたか?
thetrystero 2016年

4
defer <script defer src = " fb.me/react-0.14.7.js "></script> <script defer src =" fb.me/react-dom-0.14.7.js"></の使用を検討してくださいスクリプト > <!-your app code now-> <script defer src = "app.js"> </ script> </ body>
着陸

4
@thetrysteroいいえ、webpackは、アプリケーションが動作するDOMノードに対するアプリケーションのバンドルの相対的な場所については何も知りません。
Dan Abramov

1
このような不可解なエラー-ルートdivの下にスクリプトを置くだけで機能しました...
kchoi '26 / 06/26

1
@DanAbramovの場合はそうではありませんが、完全な終了タグなしでターゲットコンテナーを使用して同じエラーを受け取りました(たとえば、<section id = "" />)
Chris

53

/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スターターキット同形スタイルローダー


5
ReactDOM.render代わりですReact.render
Conrado Fonseca

警告:非同期でロードするようにリアクションを設定すると、競合状態が発生します。JSが実行される前にブラウザーがページの解析を終了した場合は問題ありません。ページが解析される前にJSが読み込まれると、質問と同じ問題が発生します。deferより良いオプションかもしれません
BRasmussen

16

レディ機能は、次のように使用することができます。

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

jQueryを使用したくない場合は、次のonload関数を使用できます。

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

6
DOMContentLoaded処理するよりも適切だと思いますload(これはjQueryが使用するものです)。JSでこれを行うこともできwindow.addEventListenerます。インラインハンドラーやグローバル関数は必要ありません。
Dan Abramov、2014

3
注:renderComponentは廃止されます。代わりにReact.render()を使用してください。
Tommyixi 2015年

2
私はreact-railsを使用しているため、スクリプトタグをbodyタグの下部に移動することはできませんでした。 $(document).ready問題を解決しました。ああ、はい、render代わりに使用しますrenderComponent
ltrainpr 2015

1
ReactでjQueryを使用することは非常に悪い習慣です。同時に使用することはできますが、両方を同時に使用することはできません。
aggregate116​​6877

11

ワイルドな推測ですが、index.htmlに以下を追加してみてください。

type="javascript"

このような:

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

私にとってはうまくいきました!:-)


3
ちなみに、これは私にとってtype="text/javascript"適切に機能する問題を引き起こしました。
steezeburger 2017年

それは実際に私の問題を修正しているひどいです。ちょっと悲しいですが、誰がこれに責任を負うべきか、反応するか、それともバベルですか?
ウィリアムハウリー

6

私は同じエラーに遭遇しました。私のコードを次のように変更した後、単純なタイプミスが原因であることがわかりました。

document.getElementById('root')

document.querySelector('root')

「#」がないことに注意してください

document.querySelector('#root')

他の誰かがこのエラーを解決するのを助けるために投稿するだけです。


4

はい、基本的にあなたがしたことは正しいですが、多くの場合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)DOMの準備ができdocument.onloadたときに発生するを使用します

document.addEventListener("load", function() {
  console.log("DOM is ready");
});

そこかどうかを確認するためにさらに多くのオプションがありDOMは準備ができているが、しかし短い答えはしないでくださいあなたは必ずあなたの作る前に、任意のスクリプトを実行してDOMの準備ができているすべての例で...

JavaScriptはDOM要素と連動しており、それらが利用できない場合はnullを返し、アプリケーション全体を破壊する可能性があります。そのため、実行する前にJavaScriptを実行する準備ができていることを常に確認してください...


2

反応のレンダリングにwebpackを使用し、反応でHtmlWebpackPluginを使用する場合、このプラグインは、それ自体で空のindex.htmlを作成し、jsファイルを挿入します。そのため、div要素が含まれていません。HtmlWebpackPluginのドキュメントでは、独自のインデックスを作成できます。私のwebpack.config.jsで、htmlとそのプラグインのアドレスを指定します

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>

1
HtmlWebpackPlugin静的HTMLファイルの参照に使用されているプラ​​グインを使用する理由
Harry Cho、

1

私の場合、このエラーは、新しいクラスの導入中にホットリロードが原因で発生しました。プロジェクトのその段階で、通常のウォッチャーを使用してコードをコンパイルします。


1

ReactJS.Netを使用していて、発行後にこのエラーが発生する場合:

.jsxファイルのプロパティを確認し、Build Actionがに設定されていることを確認してくださいContent。に設定されたものはNone公開されません。私はこのSOの答えからこの解決策を見つけました


1

類似または同じエラーメッセージが表示されました。私の場合、ReactJSコンポーネントをレンダリングするためのターゲットDOMノードが定義されていませんでした。HTMLターゲットノードが適切な "id"または "name"とともに、他のHTML属性(デザインのニーズに適したもの)とともに適切に定義されていることを確認します。


同様の問題がありました。ビューでは、条件が満たされた場合に予期されるターゲット要素が生成される<code> if </ code>ステートメントがありました。私の場合、条件のために適切な要素がレンダリングされませんでしたが、スクリプトが実行され、DOMに存在しない要素にコンポーネントをマウントしようとしました。
Rafal Cypcer 2018年

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>


0

あなたが得たとき:

エラー:キャッチされないエラー:ターゲットコンテナはDOM要素ではありません。

DOMContentLoadedイベントを使用するか、<script ...></script>タグを体の底に移動できます。

DOMContentLoaded初期のHTML文書が完全に仕上げ読み込みにスタイルシート、画像、サブフレームを待たずに、ロードされ、解析されたイベントが発生します。

document.addEventListener("DOMContentLoaded", function(event) {
  ReactDOM.render(<App />, document.getElementById('root'));
})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.