Hey I have a question about dynamic template loading, because I’m stuck. I’m trying to dynamically load React components based on a string reference in the database. I’ve done it with Blaze and its straight forward for me, but it seems less straightforward with React. Here’s some context about what I’m trying to accomplish:
My blaze application uses the Blaze dynamic templates to decide which page is loaded. Each page contains a reference to a template name and that template dictates the logic and layout. Example:
Blaze version
Since blaze templates are globally available its just a matter of referencing their names in the index.html. Below is a stripped down version of my app utilizing this mechanic
Main index.html
<template name="appIndex">
<div class="container">
<div class="page">
{{#if page}}
{{> UI.dynamic template=page.template data=page.configuration }}
{{else}}
<div class="loader"></div>
{{/if}}
</div>
</div>
</template>
Main index.js
Template.appIndex.helpers({
page() {
//I know that this is not reactive. Just for illustration purposes
const segments = Object.values(FlowRouter.current().params).filter((param) => !!param);
return Pages.findOne({segments});
}
});
I want to use a similar approach in React. Basically dynamically loading components based on a reference coming from the database. Loading the component itself in the render method is straightforward:
components/page.js
class Page extends Component {
renderLoader() {
return (
<div className="text-center" style={{'margin-top': '30px'}}>
<i className="fa fa-cog fa-spin fa-3x" />
</div>
)
}
render() {
if(this.props.isLoading) {
return this.renderLoader();
}
const PageComponent = this.props.page.component;
return (
<div style={{'margin-top': '30px'}}>
<PageComponent page={this.props.page.configuration} />
</div>
)
}
}
But since the components themselves are not globally defined as opposed to Blaze templates, how would I dynamically load those components even when they are coming from a different package. I’ve tried dynamic imports, but this seems to be a bit too much work (storing 3 values: package, component name and file reference). Another way would be to expose a Components object like Meteor does with the Meteor object to expose methods like Meteor.publish.
Can you guys share me some of the options that I have and why I would or would not go for the above 2 options?
Thanks!