动态创建一个可在其上安装React应用的元素

问题描述

我想使用react创建我的javascript应用程序的构建,当前仅是如下定义的单个文件。它什么也没做,只能创建div,并在挂载后继续更改hello-world文本的颜色。

import * as React from "react";
import * as ReactDOM from "react-dom";

class App extends React.Component {
    componentDidMount() {
        const colorBox = ["red","blue","green"];
        const element = document.getElementById("my-div");
        setInterval(() => {
            element.style.color = colorBox[parseInt(Math.floor(Math.random() * colorBox.length))];
        },3000);
    }

    render() {
        return (
            <div id={"my-div"}>
                Hello,World.
            </div>
        );
    }
}

ReactDOM.render(<App />,document.body.appendChild(document.createElement("div")));

我正在使用parcel js作为捆绑器。我将JavaScript打包为parcel build index.js,这在dist文件夹中创建了我的javascript文件。到现在为止还挺好。但是此刻,我在网站上使用脚本标记加载了此javascript,如下所示:

<script type="text/javascript" src="https://mycdn.com/bundle.index.js"></script>

它引发错误

    index.js:16 Uncaught TypeError: Cannot read property 'appendChild' of null
    at Object.parcelRequire.Focm.react (index.js:16)
    at f (index.js:1)
    at parcelRequire.YOwE (index.js:1)
    at index.js:1

为什么它无法访问appendChild中的document.body?我还检查了document.body是否为空。这是怎么回事我想念的是什么?

解决方法

首先,我不确定将这样的代码直接打包到这样的页面中是不是个好主意。

我对为什么会发生这种情况的猜测是与将捆绑软件加载到页面中有关。在head中吗?如果是这样,document.body可能不可用。

如果您要执行此类操作以使用与文档准备就绪相关的事件,那可能是最好的选择。

这可能会变得很复杂,具体取决于您的需求,但是如果您可以使用jQuery,则可以使用.ready()

如果没有,则可以使用various vanilla js options

,

我想您的问题与捆绑包有关,或者您在该元素可用之前要求它,因为它在这里工作正常:https://jsfiddle.net/rL6dnhps

如果从头部加载,请尝试放在主体的末端以等待主体准备就绪或将其包裹在IIFE中,如下所示:

(function() {
    // the DOM will be available here
    ReactDOM.render(<App />,document.body.appendChild(document.createElement("div")));
})();