[javascript] 불변 위반 : _registerComponent (…) : 대상 컨테이너가 DOM 요소가 아닙니다

사소한 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>

이것은 무엇을 의미 하는가?



답변

스크립트가 실행될 때 documentelement script자체는에 있기 때문에 아직 사용할 수 없습니다 head. 그것을 유지하는 유효한 해결책 반면 scripthead렌더링 DOMContentLoaded이벤트 , 그것은 심지어 더 나은 당신을 넣어 script의 맨 아래에 body A를 루트 요소를 렌더링 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 Font Loader, 브라우저 플러그인 등)는 bodyReact가 예상하지 않을 때 DOM 노드를 수정할 수 있으며 추적 및 디버그가 매우 어려운 이상한 오류를 일으킬 수 있습니다. 이 문제에 대해 자세히 알아보십시오.

script맨 아래 에 배치하는 좋은 점은 프로젝트에 React 서버 렌더링을 추가하는 경우 스크립트가로드 될 때까지 렌더링을 차단하지 않는다는 것입니다.


업데이트 : (2015 년 10 월 7 일 | v0.14 )

React.render더 이상 사용되지 않습니다 ReactDOM.render
. 대신 사용하십시오.

예:

import ReactDOM from 'react-dom';

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


답변

/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 Starter Kit , 동형 스타일 로더


답변

준비 기능은 다음과 같이 사용할 수 있습니다 :

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

jQuery를 사용하지 않으려면 다음 onload함수를 사용할 수 있습니다 .

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


답변

간단히 추측하면 index.html에 다음을 추가하는 방법은 다음과 같습니다.

type="javascript"

이처럼 :

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

나를 위해 그것은 효과가 있었다! 🙂


답변

나는 같은 오류가 발생했습니다. 내 코드를 다음과 같이 변경 한 후 간단한 오타로 인한 것으로 나타났습니다.

document.getElementById('root')

document.querySelector('root')

누락 된 ‘#’에 주목하십시오.

document.querySelector('#root')

다른 사람 이이 오류를 해결하는 데 도움이되는 경우 게시하십시오.


답변

그렇습니다. 기본적으로 JavaScript가 동기화되어 있다는 사실을 잊어 버린 것을 제외하고는 기본적으로 옳았습니다 .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하면 DOM 이 준비 되면 시작됩니다 .

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

DOM 이 준비되어 있는지 확인하는 옵션이 더 있지만 짧은 대답은 모든 경우에 DOM이 준비되어 있는지 확인하기 전에 스크립트를 실행 하지 않는 것입니다 …

JavaScript는 DOM 요소와 함께 작동하며 사용할 수없는 경우 null 을 반환 하고 전체 응용 프로그램을 중단 할 수 있습니다 … 그래서 항상 JavaScript를 실행할 준비가되어 있는지 확인하십시오 …


답변

반응을 렌더링하기 위해 웹팩을 사용하고 반응에서 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>