React - Dynamically Import Components
Since the question is really old, the answers maybe were ok. But nowadays, if someone have the same problem should use dynamic import, in order to load only the component needed and avoid to load all the different ones.
const component = React.lazy(() => import('./component.jsx'));
try the example here: demo
Here is another solution:
We get the list of needed components list = ['c1', 'c2', 'c3']
. It may be pulled from json file to an array (i use redux-store so i initiate getting forms by this.props.getForms()). But you may just create and access the list of components manually.
componentDidMount = () => {
//we get elements list from any source to redux-store
this.props.getForms();
//access redux-store to the list
const forms = this.props.configBody.sets;
//make deep object copy
const updatedState = { ...this.state };
updatedState.modules = [];
if (forms) {
//here is the very dynamic import magic: we map the import list and prepare to store the imports in Component`s state
const importPromises = forms.map(p =>
import(`../TemplateOrders/Template${p.order}`)
.then(module => {
updatedState.modules.push(module.default)
})
.catch(errorHandler(p))
)
//wait till all imports are getting resolved
Promise.all(importPromises)
.then(res =>
//then run setState
this.setState({ ...updatedState }, () => {
console.log(this.state);
}))
}
}
render() {
const forms = this.props.configBody.sets;
//we iterate through the modules and React.createElemet`s
const list = this.state.modules
? this.state.modules.map((e, i) =>
createElement(e, { key: forms[i].title }, null)
)
: [];
return (
<Fragment>
<Link to='/'>Home</Link>
<h1>hello there</h1>
//push them all to get rendered as Components
{list.map(e => e)}
</Fragment>
)
}
So when your app is loaded it pulls the needed modules.
I thought to use promises to import them, but modules are already promises.
In case we need to ajax them from server lately, so we need to split the modules before bundling with require (or something like that) dont know exactly.
import React, { Component } from 'react'
import Component1 from './Component1'
import Component2 from './Component2'
import Component3 from './Component3'
class Main extends Component {
render() {
var type = 'Component1'; // just an example
return (
<div>
{type == "Component1" && <Component1 />}
{type == "Component2" && <Component2 />}
...
</div>
)
}
}
export default Main
You can use conditional rendering insted. Hope it will help
Check this
I think there may have been some confusion as to what I was trying to achieve. I managed to solve the issue I was having and have shown my code below which shows how I solved it.
Separate File (ComponentIndex.js):
let Components = {};
Components['Component1'] = require('./Component1').default;
Components['Component2'] = require('./Component2').default;
Components['Component3'] = require('./Component3').default;
export default Components
Main File (Main.js):
import React, { Component } from 'react';
import Components from './ComponentIndex';
class Main extends Component {
render () {
var type = 'Component1'; // example variable - will change from user input
const ComponentToRender = Components[type];
return <ComponentToRender/>
}
}
export default Main
This method allows me to add/remove components very quickly as the imports are in one file and only requires changing one line at a time.