Skip to content

Instantly share code, notes, and snippets.

@davidgljay
Last active June 12, 2022 19:22
Show Gist options
  • Save davidgljay/5d7a29c5add8b360b93db838235e80a8 to your computer and use it in GitHub Desktop.
Save davidgljay/5d7a29c5add8b360b93db838235e80a8 to your computer and use it in GitHub Desktop.
Pattern for dynamically loading React components based on a config json object.
import config from '../config'
let components = {}
//For each component in the config fiel into an object
for (var i = config.length - 1; i >= 0; i--) {
components[config[i].name] = require(config[i].path).default
}
export default components
/* Alternative if this require business makes you too queasy */
// import First from './First'
// import Second from './Second'
// import Third from './Third'
// export const First = First
// export const Second = Second
// export const Third = Third
export default [
{
name:'First',
path:'./First'
},
{
name:'Second',
path:'./Second'
},
{
name:'Third',
path:'./Third'
}]
import React from 'react';
//Example components, keeping these super simple
class First extends React.Component {
render() {
return <h1>First</h1>
}
}
export default First
import React from 'react';
import Components from './ComponentIndex'
import config from '../config'
class AppComponent extends React.Component {
render() {
return (
<div className="index">
<h2>Component structure test</h2>
{config.map((comp) => {
/*Load each component in the config file in order.
* Note that the config object could also include props
* which could be passed in like so:
* <Component {..config.props} />
*/
if (Components.hasOwnProperty(comp.name)) {
let Component = Components[comp.name];
return <Component key={comp.name} />
}
})}
</div>
);
}
}
export default AppComponent;
import React from 'react';
class Second extends React.Component {
render() {
return <h1>Second</h1>
}
}
export default Second
import React from 'react';
class Third extends React.Component {
render() {
return <h1>Third</h1>
}
}
export default Third
@YannisMarios
Copy link

This worked for me:
https://gist.github.com/YannisMarios/7f3b947b46b4f79c06c79c2ff597eff0

import React, { lazy, Suspense } from 'react'
import Spinner from '../../ui/spinner/Spinner' // Some Spinner

const config = [
  {
    name: 'First',
    path: './First',
    props: {name: 'Yannis', surname: 'Marios'}
  },
  {
    name: 'Second',
    path: './Second',
    props: {name: 'John', surname: 'Doe'}
  }
]

const importedComponents = () => {
  const components = {}
  for(let i = 0; i < config.length; i++) {
    components[config[i].name] = lazy(() => import(`${config[i].path}`))
  }
  return components
}

const DynamicComponents = () => {
  const Components = importedComponents()

  const components = config.map(c => {
    const Component = Components[c.name]
    return <Suspense key={c.name} fallback={<Spinner/>}><Component key={c.name} {...c.props} /></Suspense>
  })
  return <div>{components}</div>
}

export default DynamicComponents

@kristoff2016
Copy link

Hello there,
Thank you for sharing. does it work for share props to child First.js with componentWillReceiveProps ?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment