最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to wait for in browser JSX compiler before call to render component - Stack Overflow

programmeradmin3浏览0评论

(Using the in browser JSX Transformer) When calling a react ponent from plain javascript, i get an Uncaught ReferenceError.

I try to call a React.js (0.12.2) ponent from my javascript app. I got a JQuery document.ready handler to do so.

It seams, that the in browser JSX piler needs some time before react's ponents are ready to use.

Document.ready might not be an option in that case.

See the example below:

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();
});

ponent.js:

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

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

Running this in the browser outputs in the log:

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

But when I load the app.js through the jsx transformer, by adding type="text/jsx" in the script tag, it works:

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

Is there an other way to wait for the JSX transformer to finish, instead of loading all js files with type text/jsx? And am I right, that this is really specific to the in browser JSX transformer

(Using the in browser JSX Transformer) When calling a react ponent from plain javascript, i get an Uncaught ReferenceError.

I try to call a React.js (0.12.2) ponent from my javascript app. I got a JQuery document.ready handler to do so.

It seams, that the in browser JSX piler needs some time before react's ponents are ready to use.

Document.ready might not be an option in that case.

See the example below:

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();
});

ponent.js:

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

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

Running this in the browser outputs in the log:

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

But when I load the app.js through the jsx transformer, by adding type="text/jsx" in the script tag, it works:

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

Is there an other way to wait for the JSX transformer to finish, instead of loading all js files with type text/jsx? And am I right, that this is really specific to the in browser JSX transformer

Share Improve this question asked Feb 22, 2015 at 11:20 serprimeserprime 1263 silver badges9 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I'd remend you switch to a JSX prepiler workflow if you can (like using gulp or grunt for example if you were using NodeJS). That way, you won't have to worry about this sequencing problem.

Until you can switch, I'd suggest putting your application initialization in the last text/jsx script file loaded. That way, it will always execute after the DOM has fully loaded and is ready to be used. You shouldn't need to rely on the jQuery event if you make this change.

You could even switch the last file to just be processed as test/jsx, even though it may not contain any JSX functionality currently:

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

(By the way, you shouldn't use self-closing tags for for scripts, see here).

while a prepiler workflow might be ideal, for me it's much easier to use raw jsx when developing.

to ensure all the jsx has finished piling, I use a simple wait loop in the onload trigger before real work mences:

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

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

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

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

this works with dynamic or pre-piled jsx.

发布评论

评论列表(0)

  1. 暂无评论