26

I am currently working on a CMS based project.

For which i am using the universal react redux boilerplate by erikras

I really need suggestions on handling dynamic routing

Lets take a simple scenario form the boilerplate...

In routes.js

<Route path="about" component={About}/>
<Route path="login" component={Login}/>
<Route path="survey" component={Survey}/>
<Route path="widgets" component={Widgets}/>

data.js

export const data = [
  {id: 1, property: 'Dashboard', link: '/'},
  {id: 2, property: 'Login', link: '/login'},
  {id: 3, property: 'About Us', link: '/About'},
];

now, let say on the basis of user role, the properties in json data will change

let say new property: is

{id: 4, property: 'test page', link: '/test'}

When react will render the components, how it would know the route link .. as it is not defined in the routes.js

I am not getting the right way to implement it

We need a sidebar made of specific menu content as per the user role .

Let say we are building a reservation system , there can be different user roles like admin, maintenance mode, assistant role .

So different role will have different properties, accordingly we need to generate the menu on the basis it, as the properties will definitely differ as per user role.

Thanks!!

Dev
  • 285
  • 1
  • 3
  • 7

2 Answers2

30

It is not clear from your example which component should be rendered for /test url? I suppose it is value of property key, right?

First option

You can do is something like this:

<Route path="/:page" component={Page}/>

It will allow you to render Page component for each url, that starts from / and this component will have page url inside this.props.routeParams.page. It allows you to find needed component inside Page#render:

render() {
  const url = this.props.routeParams.page;
  const PageComponent = data.find(page => page.link === url).property;
  render <PageComponent />;
}

Second option

You can generate Routes dynamically, but I'm not sure if it works (you can check it). You just should replace this part:

<Route path="about" component={About}/>
<Route path="login" component={Login}/>
<Route path="survey" component={Survey}/>
<Route path="widgets" component={Widgets}/>

with

 data.map(page => <Route path={page.link} component={page.property} key={page.id}/>)
Alexandr Subbotin
  • 1,714
  • 2
  • 17
  • 16
  • Thanks Alexandr. The second option suits my case more. i am working on generating routes dynamically with data.map(). It seems out it works, now i am looking forward to see if its nesting child elements will work . like for test component : the nesting route is: test/childItem1 , test/childItem2 , test/childItem3 and so on,, – Dev Mar 05 '16 at 03:59
  • 1st options looks good. Can you please tell how will in 2nd option, I can pass dynamic routes to the route file? – master_dodo Feb 12 '17 at 12:47
  • 1
    @Dev did you implement second option and it is working ? please let me know, i have the similar requirement as yours . – Syed Ali May 17 '17 at 07:33
  • The second won't work because `component` requires not a string but a component class (unless you're looking to render DOM elements)... see https://stackoverflow.com/q/48854497/5647260 – Andrew Li Feb 18 '18 at 17:45
  • `const url = this.props.match.params.id` work for me .Looks like their had been changed – ashad Jul 12 '19 at 19:49
-6

Third Option:

Follow the react-router example 'huge-apps' for dynamically loading routes.

The project structure provides a logical hierarchy for both the routes and the components. Their approach also uses webpack to load shared bundles with page specific bundled code. The project has a routes folder. In the example, the dynamic portion of the hierarchy is derived from data in the stubs folder which can be changed to use another data source. The approach was effective.

|____Calendar
| |____components
| | |____Calendar.js
| |____index.js
|____Course
| |____components
| | |____Course.js
| | |____Dashboard.js
| | |____Nav.js
| |____index.js
| |____routes
| | |____Announcements
| | | |____components
| | | | |____Announcements.js
| | | | |____Sidebar.js
| | | |____index.js
| | | |____routes
| | | | |____Announcement
| | | | | |____components
| | | | | | |____Announcement.js
| | | | | |____index.js
| | |____Assignments
| | | |____components
| | | | |____Assignments.js
| | | | |____Sidebar.js
| | | |____index.js
| | | |____routes
| | | | |____Assignment
| | | | | |____components
| | | | | | |____Assignment.js
| | | | | |____index.js
| | |____Grades
| | | |____components
| | | | |____Grades.js
| | | |____index.js
|____Grades
| |____components
| | |____Grades.js
| |____index.js
|____Messages
| |____components
| | |____Messages.js
| |____index.js
|____Profile
| |____components
| | |____Profile.js
| |____index.js

``` The repo doesn't include this example on the master branch anymore.

  • Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Takarii Jan 04 '17 at 15:39
  • 8
    -1 Because the link does not work and the answer by itself does not provide any information on how to solve the problem of the question – matias.g.rodriguez Mar 14 '17 at 18:43