अपरिवर्तनीय उल्लंघन: _registerComponent (…): लक्ष्य कंटेनर एक DOM तत्व नहीं है


387

मुझे यह त्रुटि एक तुच्छ प्रतिक्रिया उदाहरण पृष्ठ बनाने के बाद मिली:

बिना त्रुटि के त्रुटि: अपरिवर्तनीय उल्लंघन: _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
@ गो-ओलेग: यह ईएस 6 शॉर्ट नोटेशन है। यह मुद्दा नहीं है क्योंकि प्रतिक्रिया-उपकरण में ES6 ट्रांसपिलर है। यहाँ देखें
दान Abramov

14
मैं इस त्रुटि में भाग गया, और जैसा कि अन्य लोगों ने सुझाव दिया है, यह इसलिए है क्योंकि आपकी बंडल.जेएस फ़ाइल बहुत जल्दी लोड हो रही है। इस त्रुटि को हल करने के लिए अपने <script> टैग को शरीर में ले जाएं (समापन से पहले अंतिम पंक्ति के रूप में </ body> टैग)।
टॉड आर

2
यहाँ मदद नहीं करता है
daslicht

@daslicht मुझे आशा है कि आपको अपना उत्तर मिल गया है, लेकिन अभी इतना ही कहा गया है: डबल चेक जो आप कक्षाओं और आईडी के मिश्रण में नहीं हैं। document.getElementById ("foo") कभी, कभी, कभी ऐसा टैग ढूंढने जा रहा है जो पढ़ता है <div class = "foo">
डेव कैंटर

जवाबों:


625

जब तक स्क्रिप्ट निष्पादित की जाती है, तब तक documentतत्व अभी तक उपलब्ध नहीं है, क्योंकि scriptस्वयं में है head। हालांकि यह एक वैध समाधान है कि scriptआप इसे इवेंट में रख सकें headऔर प्रस्तुतDOMContentLoaded कर सकें , इसलिए यह बहुत बेहतर है कि आप 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 फ़ॉन्ट लोडर, ब्राउज़र प्लगइन्स, जो भी हो) bodyDOM नोड को संशोधित कर सकते हैं जब रिएक्ट इसकी उम्मीद नहीं करता है, और अजीब त्रुटियों का कारण बनता है जो ट्रेस और डीबग करने में बहुत कठिन हैं।इस मुद्दे के बारे में और अधिक पढ़ें।

scriptतल पर डालने के बारे में अच्छी बात यह है कि जब तक आप अपनी परियोजना में रिएक्ट सर्वर रेंडरिंग जोड़ते हैं, तब तक यह रेंडरिंग को ब्लॉक नहीं करेगा।


अपडेट: (० October अक्टूबर, २०१५ | v0.14 )

React.renderपदावनत किया जाता है, ReactDOM.render इसके बजाय उपयोग करें ।

उदाहरण:

import ReactDOM from 'react-dom';

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

3
मैं वेबपैक में आयात विवरण का उपयोग कर रहा हूं और फिर भी यह त्रुटि मिलती है। मैंने सोचा था कि वेबपैक स्क्रिप्ट्स लोड करने के क्रम को ध्यान में रखेगा न?
Thetrystero

4
Defer का उपयोग करने के लिए विचार करें <script defer src = " fb.me/react-0.14.7.js " > बुटीक / स्क्रिप्ट> <script defer src =" fb.me/react-dom-0.14.7.js " > बुटीक / स्क्रिप्ट > <! - अब आपका ऐप कोड -> <script defer src = "app.js"> </ script> </ body>
उतरा

4
@thetrystero नहीं, वेबपैक को आपके एप्लिकेशन के बंडल के संबंधित स्थान के बारे में कोई जानकारी नहीं है, जो DOM नोड्स पर काम करता है।
दान अब्रामोव

1
इस तरह की गूढ़ त्रुटि - बस स्क्रिप्ट को रूट डिव के नीचे रखने से यह काम हो गया ...
kchoi

1
यह @DanAbramov का मामला नहीं है, लेकिन मुझे पूर्ण समापन टैग के बिना लक्ष्य कंटेनर का उपयोग करके एक ही त्रुटि प्राप्त हुई (उदाहरण के लिए <खंड आईडी = "" />)
क्रिस

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 सामग्री लोड ।

स्रोत: रिएक्टर स्टार्टर किट , आइसोमॉर्फिक-स्टाइल-लोडर


5
इसके ReactDOM.renderबजाय है React.render
कॉनरोडो फोंसेका

चेतावनी नोट: यदि आप एसिंक्रोनस रूप से लोड करने के लिए अपनी प्रतिक्रिया सेट करते हैं, तो यह एक दौड़ की स्थिति बनाता है- यदि ब्राउज़र जेएस निष्पादित होने से पहले पृष्ठ को पार्स कर रहा है, तो आप ठीक हैं। यदि पेज को पार्स करने से पहले जेएस लोड किया जाता है, तो आप उसी मुद्दे के साथ समाप्त हो जाएंगे जो सवाल के बारे में है। deferएक बेहतर विकल्प हो सकता है
ब्राम्स्सुबेन

16

तैयार समारोह इस तरह इस्तेमाल किया जा सकता:

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

यदि आप jQuery का उपयोग नहीं करना चाहते हैं, तो आप onloadफ़ंक्शन का उपयोग कर सकते हैं :

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

6
मुझे लगता है कि DOMContentLoadedइसे संभालने के लिए भी अधिक उपयुक्त होगा load(यह वही है जो jQuery का उपयोग करता है )। आप इसे JS के साथ भी कर सकते हैं window.addEventListener, इनलाइन हैंडलर और वैश्विक कार्यों की कोई आवश्यकता नहीं है।
दान Abramov

3
ध्यान दें, renderComponent को ह्रास किया जाएगा। इसके बजाय React.render () का उपयोग करें।
टॉमीइक्सी

2
मैं प्रतिक्रिया-रेल का उपयोग कर रहा हूँ ताकि शरीर टैग के नीचे स्क्रिप्ट टैग को स्थानांतरित करना एक विकल्प नहीं था। $(document).readyसमस्या का हल किया। ओह और हाँ के renderबजाय का उपयोग करें renderComponent
ltrainpr

1
रिएक्ट के साथ jQuery का उपयोग करना बहुत बुरा अभ्यास है। या तो उपयोग करें, लेकिन एक ही समय में दोनों नहीं।
समुच्चय

11

बस एक जंगली अनुमान, कैसे के बारे में index.html निम्नलिखित को जोड़ने के लिए:

type="javascript"

इस तरह:

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

मेरे लिए यह काम किया! :-)


3
सिर्फ FYI करें, इससे मेरे लिए समस्याएँ पैदा हुईं जहाँ मैंने type="text/javascript"ठीक से काम किया।
स्टीजेबर्गर

यह भयानक है कि वास्तव में मेरा मुद्दा तय हो गया है। दुख की बात है, लेकिन यकीन नहीं है कि इस पर कौन दोषी है, प्रतिक्रिया या बेबल?
विलियम हॉली

6

मैं उसी त्रुटि में भाग गया। यह मेरे कोड को बदलने के बाद एक साधारण टाइपो के कारण हुआ:

document.getElementById('root')

सेवा

document.querySelector('root')

गायब '#' को नोटिस करें। यह होना चाहिए था

document.querySelector('#root')

बस मामले में पोस्ट करने से यह किसी और को इस त्रुटि को हल करने में मदद करता है।


4

हां, मूल रूप से आपने जो किया वह सही है, सिवाय इसके कि आप भूल जाते हैं कि जावास्क्रिप्ट कई मामलों में सिंक है, इसलिए आप अपने 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, जो डोम तैयार होने पर निकाल दिया जाता है:

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

यह जाँचने के लिए और भी विकल्प हैं कि DOM तैयार है या नहीं, लेकिन संक्षिप्त उत्तर यह नहीं है कि कोई भी स्क्रिप्ट चलाने से पहले यह सुनिश्चित करें कि आपका DOM हर मामले में तैयार है ...

जावास्क्रिप्ट डोम तत्वों के साथ काम कर रहा है और अगर वे उपलब्ध नहीं हैं, तो अशक्त हो जाएगा, पूरे आवेदन को तोड़ सकता है ... इसलिए हमेशा सुनिश्चित करें कि आप अपने जावास्क्रिप्ट को चलाने से पहले पूरी तरह से तैयार हैं ...


2

यदि आप अपनी प्रतिक्रिया देने के लिए वेबपैक का उपयोग करते हैं और अपनी प्रतिक्रिया में HtmlWebpackPlugin का उपयोग करते हैं, तो यह प्लगइन अपने खाली index.html को स्वयं बनाता है और इसमें js फ़ाइल इंजेक्ट करता है, इसलिए इसमें div एलिमेंट नहीं होता है, क्योंकि HtmlWebpackPlugin डॉक्स के रूप में आप अपना खुद का इंडेक्स बना सकते हैं। 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>

1
HtmlWebpackPluginस्थैतिक HTML फ़ाइल को संदर्भित करने के लिए उपयोग किए जाने पर प्लग इन का उपयोग क्यों करें ?
हैरी चो

1

मेरे मामले में यह त्रुटि गर्म लोडिंग के कारण हुई, जबकि नई कक्षाएं शुरू करते समय। परियोजना के उस चरण में, अपने कोड को संकलित करने के लिए सामान्य प्रहरी का उपयोग करें।


1

ReactJS.Net का उपयोग करने वालों के लिए और एक प्रकाशन के बाद यह त्रुटि प्राप्त करना:

अपनी .jsx फ़ाइलों के गुणों की जाँच करें और सुनिश्चित करें Build Actionकि सेट किया गया है Content। जिन्हें Noneप्रकाशित नहीं किया जाएगा। मैं इस एसओ जवाब से इस समाधान पर आया था ।


1

मैं इसी तरह के / त्रुटि संदेश में भाग गया। मेरे मामले में, मेरे पास लक्ष्य DOM नोड नहीं था जो कि परिभाषित किए गए ReactJS घटक को प्रस्तुत करना है। सुनिश्चित करें कि HTML लक्ष्य नोड को उचित रूप से "आईडी" या "नाम" के साथ परिभाषित किया गया है, अन्य HTML विशेषताओं के साथ (आपकी डिज़ाइन की आवश्यकता के लिए उपयुक्त)


मेरा भी ऐसा ही मुद्दा था। यह देखते हुए कि मेरे पास <code> if </ code> स्टेटमेंट है जहाँ अपेक्षित टार्गेट एलिमेंट जेनरेट किया जाना चाहिए अगर कंडीशन पूरी हो गई है। मेरे मामले में हालत की वजह से उचित तत्व प्रस्तुत नहीं किया गया था, लेकिन स्क्रिप्ट को निष्पादित किया गया और उस तत्व पर घटक को माउंट करने का प्रयास किया गया जो डोम में मौजूद नहीं था।
रफाल साइपर

0

यह आसान है बस मूल HTML सीएसएस 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 दस्तावेज़ पूरी तरह से लोड किया गया है और पार्स, स्टाइलशीट, छवियां, और खत्म करने के लिए लोड हो रहा है subframes का इंतजार किए बिना।

document.addEventListener("DOMContentLoaded", function(event) {
  ReactDOM.render(<App />, document.getElementById('root'));
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.