Değişmez İhlal: _registerComponent (…): Hedef kapsayıcı bir DOM öğesi değil


388

Önemsiz bir React örnek sayfası yaptıktan sonra bu hatayı alıyorum:

Yakalanmayan Hata: Değişmez İhlal: _registerComponent (...): Hedef kapsayıcı bir DOM öğesi değil.

İşte benim kod:

/** @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>

Ne anlama geliyor?


8
@ go-oleg: Bu ES6 kısa gösterimidir. Sorun bu değil, çünkü tepki araçlarında ES6 aktarıcı var. Buraya bakın
Dan Abramov

14
Aynı hatayla karşılaştım ve diğerlerinin önerdiği gibi, bundle.js dosyanız çok erken yükleniyor. Bu hatayı çözmek için <script> etiketinizi gövdeye taşıyın (kapanış </body> etiketinden önceki son satır olarak).
Todd R

2
burada yardımcı olmuyor
daslicht

@daslicht Umarım cevabınızı bulmuşsunuzdur ama öyle söylenir: ÇİFT Sınıfları ve kimlikleri karıştırmamanızı sağlayın. document.getElementById ("foo") hiçbir zaman, asla, hiç <div class = "foo"> yazan bir etiket bulamayacak
Dave Kanter

Yanıtlar:


626

Komut dosyası yürütüldüğünde, documentöğe henüz mevcut değildir, çünkü scriptkendisi head. O tutmak için geçerli bir çözüm olmakla birlikte scriptiçinde headve üzerinde işlemek DOMContentLoadeddurumunda , bu daha da iyidir dayan scripten alt de body ve bir kök bileşeni işlemek divböyle ondan önce:

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

ve içinde bundle.js:

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

Bunun divyerine her zaman iç içe yerleştirmeniz gerekir body. Aksi halde, her türlü üçüncü taraf kodu (Google Yazı Tipi Yükleyicisi, tarayıcı eklentileri, ne olursa olsun) bodyReact beklemediğinde DOM düğümünü değiştirebilir ve izlemesi ve hata ayıklaması çok zor olan garip hatalara neden olabilir. Bu sorun hakkında daha fazla bilgi edinin.

En scriptaltta koymakla ilgili güzel bir şey , projenize React sunucusu oluşturmayı eklerseniz komut dosyası yüklenene kadar oluşturmayı engellememesidir.


Güncelleme: (07 Ekim 2015 | v0.14 )

React.renderkullanımdan kaldırılmışsa ReactDOM.render bunun yerine kullanın.

Misal:

import ReactDOM from 'react-dom';

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

3
Web paketinde içe aktarma ifadeleri kullanıyorum ve yine de bu hatayı alıyorum. Web paketinin yükleme komut dosyalarının sırasına dikkat edeceğini düşündüm hayır?
thetrystero

4
Defer <script defer src = " fb.me/react-0.14.7.js " ></script> <script defer src =" fb.me/react-dom-0.14.7.js"></ script > <! - uygulama kodunuz şimdi -> <script defer src = "app.js"> </script> </body>
indi

4
@thetrystero Hayır, webpack, uygulamanızın paketinin üzerinde çalıştığı DOM düğümlerine göreli yeri hakkında bilgi sahibi değildir.
Dan Abramov

1
Böyle şifreli hata - sadece kök div altına komut dosyası koymak ...
kchoi

1
@DanAbramov için geçerli değil ancak tam bir kapanış etiketi olmayan bir hedef kapsayıcı kullanarak aynı hatayı aldım (örneğin, <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 +)

Not : <script async src="..."></script>Başlığa sahip olmak, tarayıcının HTML içeriği yüklenmeden önce JavaScript paketini indirmeye başlamasını sağlar .

Kaynak: React Başlangıç ​​Kiti , izomorfik tarzda yükleyici


5
Bunun ReactDOM.renderyerine React.render.
Conrado Fonseca

Uyarı notu: Tepkinizi eşzamansız olarak yüklenecek şekilde ayarlarsanız, bir yarış koşulu oluşturur; tarayıcı, JS yürütülmeden önce sayfayı ayrıştırmayı bitirirse sorun yok. JS, sayfa ayrıştırılmadan önce yüklenirse, sorunun aynı sorunla karşılaşırsınız. deferdaha iyi bir seçenek olabilir
BRasmussen

16

hazır fonksiyon şöyle kullanılabilir:

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

JQuery kullanmak istemiyorsanız, şu onloadişlevi kullanabilirsiniz :

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

6
Ben DOMContentLoadedbile işlemek için daha uygun olacağını düşünüyorum load(bu jQuery kullanır ). Bunu JS'de window.addEventListener, satır içi işleyicilere ve genel işlevlere gerek olmadan da yapabilirsiniz .
Dan Abramov

3
RenderComponent öğesinin amortismana tabi tutulacağını unutmayın. Bunun yerine React.render () öğesini kullanın.
Tommyixi

2
Vücut etiketinin altına komut dosyası etiketi taşımak bir seçenek değildi tepki tepki rayları kullanıyorum. $(document).readysorunu çözdü. Oh ve evet renderyerine kullanın renderComponent.
ltrainpr

1
React ile jQuery kullanmak son derece kötü bir uygulamadır. İkisini de kullanın, ancak her ikisini aynı anda kullanmayın.
aggregate1166877

11

sadece vahşi bir tahmin, index.html'ye eklemeye ne dersiniz:

type="javascript"

bunun gibi:

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

Benim için çalıştı! :-)


3
Sadece FYI, bu type="text/javascript"düzgün çalıştığım yerde benim için sorunlara neden oldu .
steezeburger

Bu gerçekten benim sorunum düzeltildi korkunç. biraz üzücü, ama bunu kimin suçlayacağı, tepki göstereceği veya babil olacağından emin değil misiniz?
William Howley

6

Aynı hatayla karşılaştım. Kodumu değiştirdikten sonra basit bir yazım hatası nedeniyle ortaya çıktı:

document.getElementById('root')

için

document.querySelector('root')

Eksik '#' dikkat edin

document.querySelector('#root')

Başkalarının bu hatayı çözmesine yardımcı olması durumunda göndermek.


4

Evet, temelde yaptığınız doğrudur, ancak JavaScript'in birçok durumda senkronize edildiğini unutmayın, bu nedenle DOM'unuz yüklenmeden önce kodu çalıştırırsanız, bunu çözmenin birkaç yolu vardır:

1) DOM'un tamamen yüklü olup olmadığını kontrol edin , sonra ne istersen yapın, örneğin DOMContentLoaded dinleyebilirsiniz :

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

2) Çok yaygın bir yol, komut dosyası etiketini document(gövde etiketinden sonra) en altına eklemektir :

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

3) window.onloadTüm sayfa yüklendiğinde tetiklenen (img vb.)

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

4) DOM hazır document.onloadolduğunda tetiklenir :

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

DOM'un hazır olup olmadığını kontrol etmek için daha fazla seçenek var , ancak kısa yanıt, DOM'nizin her durumda hazır olduğundan emin olmadan önce herhangi bir komut dosyası KULLANMAYIN ...

JavaScript, DOM öğeleriyle birlikte çalışıyor ve kullanılamıyorsa, null döndürecek , tüm uygulamayı kırabilir ... bu yüzden her zaman sizden önce JavaScript'inizi çalıştırmaya tamamen hazır olduğunuzdan emin olun ...


2

Tepkinizi oluşturmak için webpack'i kullanır ve reaksiyonunuzda HtmlWebpackPlugin'i kullanırsanız, bu eklenti boş index.html dosyasını kendi başına oluşturur ve içindeki js dosyasını enjekte eder, böylece HtmlWebpackPlugin dokümanları olarak kendi indeksinizi oluşturabilirsiniz. html'yi ve adresini bu eklentiye webpack.config.js dosyamda ver

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

ve bu benim index.html dosyam

<!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
HtmlWebpackPluginStatik HTML dosyasına başvurmak için neden eklentiyi kullanmalıyım ?
Harry Cho

1

Benim durumumda, bu hata yeni sınıflar getirilirken sıcak yeniden yüklemeden kaynaklandı. Projenin bu aşamasında kodunuzu derlemek için normal gözlemcileri kullanın.


1

ReactJS.Net'i kullanan ve bir yayınlamadan sonra bu hatayı alan kullanıcılar için:

.Jsx dosyalarınızın özelliklerini kontrol edin ve Build Actionolarak ayarlandığından emin olun Content. Olarak ayarlanmış olanlar Noneyayınlanmayacak. Bu SO cevabından bu çözümü buldum .


1

Benzer / aynı hata mesajıyla karşılaştım. Benim durumumda, ReactJS bileşenini tanımlanmış hale getirmek için hedef DOM düğümü yoktu. HTML hedef düğümünün, diğer HTML özellikleriyle (tasarım gereksiniminize uygun) uygun "id" veya "name" ile iyi tanımlandığından emin olun


Benzer bir sorun yaşadım. Görünümde, koşul karşılandığında beklenen hedef öğenin oluşturulması gereken <code> if </code> deyimim vardı. Benim durumumda uygun öğe koşul nedeniyle oluşturulmadı, ancak komut dosyası çalıştırıldı ve DOM'da bulunmayan öğeye bileşen takmaya çalıştı.
Rafal Cypcer

0

basit HTML CSS js yapmak ve komut dosyasını js'den oluşturmak kolaydır

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

Elinizde:

Hata: Yakalanmadı Hata: Hedef kapsayıcı bir DOM öğesi değil.

DOMContentLoaded etkinliğini kullanabilir veya <script ...></script>etiketinizi vücudunuzun alt kısmına taşıyabilirsiniz .

DOMContentLoaded ilk HTML belgesi tamamen bitirmek yükleme stil, resimler ve alt çerçeveleri beklemeden yüklenir ve ayrıştırıldı olayı harekete.

document.addEventListener("DOMContentLoaded", function(event) {
  ReactDOM.render(<App />, document.getElementById('root'));
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.