(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
2 Answers
Reset to default 4I'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 script
s, 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
.