Reputation: 1564
I am currently building app in React.js that is suppose to be a advanced widget. Main requirement is that app should initialise only when at some point in time someone will execute function:
startApp({
someData: 'test',
wrap: 'domSelector'
});
i found this article Link, where author claims you can do this:
<div id="MyApp"></div>
<script>
window.runReactApplication({
user: { name: 'BTM', email: '[email protected]' }
}, document.querySelector('#MyApp'));
</script>
and index.js
function runApplication(data, node) {
ReactDOM.render(<App data={data} />, node);
}
window.runReactApplication = runApplication;
It doesnt work for me as i get runReactApplication
is undefined error.
Just out of curiosity i tried to wrap execution around timeout
and it worked:
<script>
setTimeout(function() {
window.runReactApplication({
user: { name: 'BTM', email: '[email protected]' }
}, document.querySelector('#MyApp'));
}, 150);
</script>
i can guess that in production its not a big problem because i can include app code first and then script so i have guarantee that function is added to the window.
But in development environment its a problem i dont know how to solve, and having timeout around function is obviously crazy. Anyone has an idea ?
Upvotes: 0
Views: 1342
Reputation: 1342
You can use dynamic imports instead of setTimeout.
Let's say all of your react logic is bundled inside of index.js
. Simply do the following to ensure that index.js
has been downloaded and run before the desired DOM attachment:
import('index.js').then(() => {
window.runReactApplication({
user: { name: 'BTM', email: '[email protected]' }
}, document.querySelector('#MyApp'));
}
If you want to preload the index.js
file for optimal speed, simply add
<script src="index.js"></script>
to the head of your index.html
file.
In the broader context, however, I am not sure why your startApp
function wouldn't simply be:
function startApp(params){
const {data, selector} = params;
ReactDOM.render({
<App data={data} />
}, document.querySelector(selector));
}
And you could just bind this as a callback to whatever html event you want (i.e., onClick
for a button, onLoad
for the document loading, etc.).
button.onclick = startApp({data:{email: [email protected]}, selector: 'domSelector'});
Upvotes: 2