Reputation:
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
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
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