Mevia
Mevia

Reputation: 1564

react init app only after calling function in html file

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

Answers (1)

Jclangst
Jclangst

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

Related Questions