如何在调用渲染组件之前在浏览器 JSX 编译器中等待

How to wait for in browser JSX compiler before call to render component

(使用浏览器中的 JSX Transformer)当从普通 javascript 调用 React 组件时,我得到一个 Uncaught ReferenceError.

我尝试从我的 javascript 应用调用 React.js (0.12.2) 组件。我有一个 JQuery document.ready 处理程序来执行此操作。

看起来,浏览器中的 JSX 编译器需要一些时间才能准备好使用 React 的组件。

Document.ready 在这种情况下可能不是一个选项。

参见下面的示例:

index.html:

<!DOCTYPE html>
<html>
<head lang="en">
    <script src="jquery-2.1.3.min.js"></script>

    <script src="react-0.12.2/JSXTransformer.js"></script>
    <script src="react-0.12.2/react.js"></script>

    <script type="text/jsx" src="reactComponent.js"/>

    <script src="app.js"/>
</head>
<body>
    <div id="target"></div>
</body>

app.js:

$(function () {
        console.log("app.js: " + typeof MyComponent);
        init();
});

component.js:

var MyComponent = React.createClass({
        render: function () {
            return (<div>works</div>)
        }
});

function init() {
        console.log("init: " + typeof MyComponent);
        React.renderComponent(<MyComponent/>, document.getElementById("target"));
}

运行 浏览器在日志中输出:

app.js: undefined
app.js: Uncaught ReferenceError: init is not defined

但是当我通过 jsx 转换器加载 app.js 时,通过在脚本标签中添加 type="text/jsx",它起作用了:

app.js: function
reactComponent.js: init: function

有没有其他方法可以等待 JSX 转换器完成,而不是加载类型为 text/jsx 的所有 js 文件? 我是对的吗,这真的是特定于浏览器中的 JSX 转换器

如果可以,我建议您切换到 JSX 预编译器工作流程(例如,如果您使用的是 NodeJS,则使用 gulpgrunt)。这样,您就不必担心这个排序问题了。

在您可以切换之前,我建议您将应用程序初始化放在最后加载的 text/jsx 脚本文件中。这样,它将始终在 DOM 完全加载并准备好使用后执行。如果进行此更改,则不需要依赖 jQuery 事件。

您甚至可以将最后一个文件切换为仅作为 test/jsx 处理,即使它当前可能不包含任何 JSX 功能:

<script src="app.js" type="text/jsx"></script>

(顺便说一下,您不应该为 script 秒使用自闭标签,请参阅 here)。

虽然预编译器工作流程可能是理想的,但对我来说,在开发时使用原始 jsx 更容易。

为了确保所有 jsx 都已完成编译,我在实际工作开始之前在 onload 触发器中使用了一个简单的等待循环:

  <script>
    'use strict';
    let i = 0;
    function init() {

      // limit loops if compiling problems
      if( i++ > 5 ) return;

      // last item in last .jsx has not been compiled
      if( !LastDefinedComponent ) return setTimeout( init, 50 );

      // do real work here
    }
  </script>
  ...
  <body onload='init()' >

这适用于动态或预编译 jsx