在主体中动态添加的脚本执行之前,在主体中动态添加的脚本执行

时间:2019-04-15 21:06:47

标签: reactjs react-dom

我有一个HTML页面,该页面向其他域中托管的react页面发出get请求。一次,我得到页面响应,将JS从请求页面的头部复制到页面的头部,主体部分中可用的脚本也是如此。

请求的页面是一个反应页面,其中在头部包含react和react-dom,在主体区域包含其他JS块,这将复制到我页面的同一部分。

我认为,任何复制到页面头部的脚本都会立即阻止页面执行,并且一旦头部中的所有脚本都执行完,那么仅会执行主体脚本。

我收到“未定义ReactDOM”的间歇性客户端错误。似乎复制到正文中的脚本在完全执行头部中的脚本之前已得到执行。

ReactJS和ReactDOM JS位于页面的顶部,而大块的错误位于正文中。

external "ReactDOM":1 Uncaught ReferenceError: ReactDOM is not defined
    at Object.faye (external "ReactDOM":1)
    at f (bootstrap:83)
    at Module.7n5H (tes1.ts:18)
    at f (bootstrap:83)
    at Object.0 (test2.ts:114)
    at f (bootstrap:83)
    at t (bootstrap:45)
    at Array.r [as push] (bootstrap:32)
    at 0.9efbe0e7cdf36824.chunk.js?_=1555361723703:1 faye @ external "ReactDOM":1 f @ bootstrap:83 7n5H @ tes1.ts:18 f @ bootstrap:83 0 @ test2.ts:114 f @ bootstrap:83 t @ bootstrap:45 r @ bootstrap:32 (anonymous) @ 0.9efbe0e7cdf36824.chunk.js?_=1555361723703:1

1 个答案:

答案 0 :(得分:0)

这是非常简单的,它实际上与头或主体中的代码无关,获取反应文件的调用有点慢,因此不会及时将代码放入主体中使用它,因此它是未定义的

例如问题

// this is the we will put in the body 
// log the react object to the console simple
let body = "console.log(React)"

// im using a button to make it easier to understand
document.querySelector('input').onclick = () => {


  // here we are assing a scrupt tag to the head
  // with the link to the react lib
  let headscript = document.createElement('script');
  headscript.src = "https://unpkg.com/react@15/dist/react.js"
  document.querySelector('head').appendChild(headscript);


  // and here we are logging the React object
  // from the body
  let bodyscript = document.createElement('script');
  bodyscript.innerHTML = body;
  document.querySelector('body').appendChild(bodyscript);
};
Click once and wait a bit then click again
<br>
<input type="button" value="click me">

如您所见,这只是异步操作的老问题,解决方案是使用promises。

演示

let body = "console.log(React)"
document.querySelector('input').onclick = () => {
  // request to get the code
  fetch("https://unpkg.com/react@15/dist/react.js")
    // returning it as plain text because that what it is
    .then(response => response.text())
    .then(data => {
      // same as before
      let headscript = document.createElement('script');
      headscript.innerHTML = data;
      document.querySelector('head').appendChild(headscript);

      // and because all code inside the reac lib is not async
      // this is safe to call right after
      let bodyscript = document.createElement('script');
      bodyscript.innerHTML = body;
      document.querySelector('body').appendChild(bodyscript);
    })
};
<input type="button" value="click me">