1

I'm using react router and I would like to redirect to a detailed page on a click on a row.

Here is my component

<Table
  model={TypeModel}
  source={this.props.types}
  selectable={false}
  onRowClick={index => this.context.router.push(`/dashboard/types/${this.props.types[index].id}`)}
/>

On click the url the changed, but my page remains the same. I defined the routes like this

{
  path: '/dashboard',
  component: requireAuthentication(DashboardLayout),
  indexRoute: Dashboard,
  childRoutes: [{
    path: 'types',
    indexRoute: TypeListRoute(store),
    childRoutes: [
      TypeDetailsRoute(store) // The path of this route is :id
    ]
  }]
}

I can not find why, this is working everywhere else in the application. I also checked and tried this threads

Did I miss something ?


More details

My router looks like

const routes = createRoutes(store)
<Router history={browserHistory} children={routes} />

with the following createRoutes method

createRoutes = store => ({
  childRoutes: [{
    path: '/',
    component: HomeLayout,
    indexRoute: Home,
    childRoutes: [
      LoginRoute(store),
      LogoutRoute(store),
      SignupRoute(store)
    ]
  }, {
    path: '/dashboard',
    component: requireAuthentication(DashboardLayout),
    indexRoute: Dashboard,
    childRoutes: [
      DeviceRoute(store),
      UserRoute(store),
      {
        path: 'types',
        indexRoute: TypeListRoute(store),
        childRoutes: [
          TypeDetailsRoute(store)
        ]
      }
    ]
  }]
})

The DashboardLayout is a react component that wrap children into some components

export class DashboardLayout extends React.Component {
  constructor (props) {
    super(props)
    this.children = props.children
  }

  render () {
    return ( 
      <Layout theme={drawerTheme}>
        <NavDrawer pinned >...</NavDrawer>
        <Panel>
          {this.children}
        </Panel>
      </Layout>
    )
  }
}

The TypeListRoute looks like

export const TypeListRoute = store => ({
  getComponent (nextState, cb) {
    require.ensure([], (require) => {
      const Type = require('./containers/TypeContainer').default

      const reducer = require('./modules/type').default

      injectReducer(store, { key: 'type', reducer })

      cb(null, Type)
    }, 'type')
  }
})

where TypeContainer returns a connected (to redux store) Table from 'react-toolbox`

TypeDetailsRoute is quite the same, but I specified a path

export const TypeDetailsRoute = store => ({
  path: ':id',
  getComponent (nextState, cb) {
    require.ensure([], (require) => {
      const Type = require('./containers/TypeDetailsContainer').default

      const reducer = require('./modules/type').default

      injectReducer(store, { key: 'type', reducer })

      cb(null, Type)
    }, 'type')
  }
})

Here TypeDetailsContainer return s something completely different thant a Table. I tried with a simple h1 and I still have the error

Community
  • 1
  • 1
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77
  • I see you are async loading reducers and probably using `store.replaceReducer`. Is that working fine? I mean I used to see similar behaviour; the route changes but the new page doesn't render because replacing reducer went wrong and threw some error in my console. :) – yadhu Nov 20 '16 at 11:14
  • It seems to work fine. It is working with other routes and I have not a single error in the console – ThomasThiebaud Nov 21 '16 at 08:36
  • do you have a github link of the entire project? – yadhu Nov 21 '16 at 09:12
  • I'm afraid no, this is a company project and I have no rights to share it – ThomasThiebaud Nov 21 '16 at 09:19

2 Answers2

2

You can use the Link component to accomplish this:

import { Link } from 'react-router'

...

<Link to={`/dashboard/types/${this.props.types[index].id}`}>Dashboard page</Link>
Lance
  • 75,200
  • 93
  • 289
  • 503
  • I'm using `react-toolbox` `Table` component, so I don't know if I can change all rows by a `Link`. Is there an equivalent method that can be called ? – ThomasThiebaud Nov 15 '16 at 17:22
  • It seems that the `Link` component is using the `push` method also ([sources](https://github.com/ReactTraining/react-router/blob/master/modules/Link.js)) – ThomasThiebaud Nov 15 '16 at 17:26
  • @ThomasThiebaud can you update the question with the components being rendered from the ``. If the URL is changing but the page visually isn't updating, then it's likely that React is saying "nothing has changed, no re-rendering necessary". So I don't think it has anything to do with the routes (your method should work fine). – Lance Nov 15 '16 at 18:03
  • I added more details into my questions – ThomasThiebaud Nov 15 '16 at 19:06
0

I resolved it !!!

In the createRoutes method, I have to change the root childRoutes by its asynchronous version getChildRoutes.

So the createRoutes method becomes (TypeRoute regroups both TypeListRoute and TypeDetailRoute)

export const createRoutes = store => ({
  getChildRoutes (nextState, cb) {
    cb(null, [{
      path: '/',
      component: HomeLayout,
      indexRoute: Home,
      childRoutes: [
        LoginRoute(store),
        LogoutRoute(store),
        SignupRoute(store)
      ]
    }, {
      path: '/dashboard',
      component: requireAuthentication(DashboardLayout),
      indexRoute: Dashboard,
      childRoutes: [
        DeviceRoute(store),
        UserRoute(store),
        TypeRoute(store)
      ]
    }])
  }
})
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77