web-dev-qa-db-fra.com

Violation invariante: _registerComponent (...): le conteneur cible n'est pas un élément DOM

Je reçois cette erreur après une page d’exemple trivial de React:

Erreur non capturée: violation invariante: _registerComponent (...): le conteneur cible n'est pas un élément DOM.

Voici mon 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>
<head>
  <script src="/bundle.js"></script>
</head>
<body>
</body>
</html>

Qu'est-ce que ça veut dire?

342
Dan Abramov

Au moment où le script est exécuté, l'élément document n'est pas encore disponible, car script est lui-même dans la variable head. Bien qu'il soit judicieux de conserver script dans head et restituer un événement DOMContentLoaded , il est encore préférable de placer votre script tout en bas de la bodyet restituer le composant racine en un div avant ça comme ça:

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

et dans le bundle.js, appelez:

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

Vous devriez toujours rendre à une div imbriquée au lieu de body. Sinon, toutes sortes de codes tiers (Google Font Loader, plugins de navigateur, etc.) peuvent modifier le nœud DOM body lorsque React ne s'y attend pas et provoquer des erreurs étranges qui sont très difficiles à suivre et à déboguer. En savoir plus sur ce problème.

Le bon côté de mettre script en bas est qu’il ne bloque pas le rendu avant le chargement du script si vous ajoutez le rendu React Server à votre projet.


Mise à jour: (07 octobre 2015 | v0.14 )

React.render est obsolète, utilisez ReactDOM.render au lieu.

Exemple:

import ReactDOM from 'react-dom';

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

/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 +)

Note: La présence de <script async src="..."></script> dans l'en-tête garantit que le navigateur va commencer à télécharger le bundle JavaScript avant Le contenu HTML est chargé.

Source: Kit de démarrage React , chargeur de style isomorphe

52
Konstantin Tarkus

la fonction ready peut être utilisée comme ceci: 

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

Si vous ne voulez pas utiliser jQuery, vous pouvez utiliser la fonction onload:

<body onload="initReact()">...</body>
15
nils petersohn

juste une supposition sauvage, que diriez-vous d'ajouter à index.html ce qui suit: 

type="javascript"

comme ça:

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

Pour moi cela a fonctionné! :-)

9
taquiles

J'ai rencontré la même erreur. Cela s'est avéré être causé par une simple faute de frappe après avoir changé mon code de

document.getElementById('root')

à

document.querySelector('root')

Remarquez le '#' manquant. Il aurait dû être 

document.querySelector('#root')

Il suffit de poster au cas où cela aiderait quelqu'un d'autre à résoudre cette erreur.

4
mangakid

Oui, en gros, ce que vous avez fait est correct, sauf que vous oubliez que JavaScript est souvent synchronisé. Par conséquent, si vous exécutez le code avant votreDOMest chargé, il existe plusieurs moyens de résoudre ce problème:

1) Vérifiez siDOMest complètement chargé, puis faites ce que vous voulez, vous pouvez écouter DOMContentLoaded par exemple:

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

2) La méthode la plus courante consiste à ajouter la balise script au bas de votre document (après la balise body):

<html>
  <head>
  </head>
  <body>
  </body>
  <script src="/bundle.js"></script>
</html>

3) Utilisation de window.onload, qui est déclenché lorsque la page entière est chargée (img, etc.)

window.addEventListener("load", function() {
  console.log("Everything is loaded");
});

4) Utilisation de document.onload, qui est déclenché lorsque leDOMest prêt:

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

Il y a encore plus d'options pour vérifier siDOMest prêt, mais la réponse courte est NE PAS exécuter un script avant de vous assurer que votre DOM est prêt dans tous les cas ...

JavaScript fonctionne avec les élémentsDOMet s'ils ne sont pas disponibles, ils renverront null , ce qui risquerait de casser l'application dans son intégralité ... alors assurez-vous toujours que vous êtes prêt à exécuter votre JavaScript avant vous. faire...

3
Alireza

Dans mon cas, cette erreur a été provoquée par un rechargement à chaud, lors de l'introduction de nouvelles classes. Dans cette phase du projet, utilisez des observateurs normaux pour compiler votre code.

1
Micros

J'ai rencontré un message d'erreur similaire/même. Dans mon cas, je n'avais pas le noeud DOM cible qui doit rendre le composant ReactJS défini. Assurez-vous que le noeud cible HTML est bien défini avec "id" ou "nom" approprié, ainsi que d'autres attributs HTML (adaptés à vos besoins en matière de conception).

1
anie codeskol

si vous utilisez webpack pour rendre votre réaction et que vous utilisez HtmlWebpackPlugin dans votre réaction, ce plugin génère son index.html vierge et lui injecte un fichier js, de sorte qu'il ne contienne pas d'élément div. et donner son adresse à ce plugin, dans mon webpack.config.js

 plugins: [

        new HtmlWebpackPlugin({
            title: 'dev',
            template: 'dist/index.html'
        })
    ],

et ceci est mon fichier 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>
0

c’est simple, il suffit de créer le code HTML de base CSS js et restituer le script depuis 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

utilisez ces src dom dans le fichier index.html et faites un lien avec le fichier js

0
LOVENEET SINGH

Pour ceux qui utilisent ReactJS.Net et obtiennent cette erreur après une publication:

Vérifiez les propriétés de vos fichiers .jsx et assurez-vous que Build Action est défini sur Content. Ceux définis à None ne seront pas publiés. Je suis tombé sur cette solution de cette SO réponse .

0
Jecoms