ThomasThiebaud ThomasThiebaud - 14 days ago 9
React JSX Question

React router push only changes the url

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

Answer

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)
      ]
    }])
  }
})
Comments