user1177440
user1177440

Reputation:

React Router 4 dynamic components loaded on the fly from database

I'm migrating to React Router 4.11 from 2.5.1. In the older version, my ISOMORPHIC/UNIVERSAL app retrieves the routes/components dynamically from a database at startup and I want to retain that same functionality with 4.11.

In the 2.5.1 version of react-router, I was able to load routes & components dynamically from the database by calling _createRouter with the routes parameter being the data retrieved from my db as such:

////////////////////////
// from client entry.js
////////////////////////
async function main() {
  const result = await _createRouter(routes)
  ReactDOM.render(      
      <Provider store={store} key="provider">
        <Router history={history}>
          {result}
        </Router>
      </Provider>
    dest
 );
}

//////////////////////
// from shared modules
//////////////////////
function _createRouter(routes) {
     const childRoutes = [ // static routes, ie Home, ForgotPassword, etc];

      ////////////////////////
      // crucial part here
      ////////////////////////
      routes.map(route => {
        const currComponent = require('../../client/components/' + route.route + '.js');
        const obj = {
          path: route.route,
          component: currComponent
        };
        childRoutes.push(obj)
      });

      childRoutes.push({path: '*', component: NotFoundComponent});
      return { path: '', component: .APP, childRoutes: childRoutes };
    }

I am frustrated that I cannot find any docs on performing the same event in 4.11. Every example shows the routes hard coded like so:

render() {
    return (
          <Route path='/' component={Home} />
          <Route path='/home' component={About} />
          <Route path='/topics' component={Topics} />
   )
}

This does not appear real-world to me especially for large apps.

Can anyone point me in the direction of accomplishing the same success I had in 2.5.1 with 4.11 insofar as being able to dynamically load my routes/components on the fly from a database?

Thanks much !

Upvotes: 0

Views: 1827

Answers (2)

Can Acar
Can Acar

Reputation: 11

Maybe this code is the solution to this issue. "dynamic route import component"

import React, {
    Component
} from "react";

const Containers = () => ( < div className = "containers" > Containers < /div>);

class ComponentFactory extends Component{constructor(props){super(props);this.state={RouteComponent:Containers}}
    componentWillMount() {
        const name = this.props.page;
        import ('../pages/' + name + '/index').then(RouteComponent => {
            return this.setState({
                RouteComponent: RouteComponent.default
            })
        }).catch(err => console.log('Failed to load Component', err))
    }
    render() {
        const {RouteComponent } = this.state;
        return (<RouteComponent { ...this.props  }/> );
    }
}
export default ComponentFactory



 <Route path="/:page"
        render={rest => <ComponentFactory
        page={rest.match.params.page}
        {...rest}/>}/>

Upvotes: 1

Crysfel
Crysfel

Reputation: 8158

In the new version, each route is just a regular react component. Therefore, you should be able to dynamically create routes as you'd create any other component.

render() {
  const { routes } = this.props;

  return (
    <div>
      {
        routes.map(route => <Route path={route.path} component={route.component} />)
      }
    </div>
  );
}

You will also need to dynamically import your components before trying to render the routes.

Upvotes: 0

Related Questions