react-redux-starter-kit icon indicating copy to clipboard operation
react-redux-starter-kit copied to clipboard

Question - Injecting reducer into parent and child routes

Open nicklee1990 opened this issue 8 years ago • 2 comments

Summary of question Is there a way of injecting a reducer for a route and all it's child routes using injectReducer in the parent route definition?

Detailed Description I'm injecting a reducer for my index route (/projects) and it works fine. My child route /projects/:id also needs the reducer to be injected because the projects slice of the state tree contains data it needs (there is a key called projectsById which contains the details for each project). If I visit the child route after the index route it works fine because the reducer has been injected. However if I visit /projects/:id the route does not load because the reducer has not been injected, shown by the message Cannot read property 'projectsById' of undefined since state.projects is undefined. My temporary solution was to just inject the reducer in getChildRoutes but is there a better way of doing this? The copy/paste felt a bit dirty. My code which works at the moment:

  getIndexRoute (partialNextState, callback) {
    require.ensure([], function (require) {
      /*  Add the reducer to the store on key 'projects'  */
      const reducer = require('./modules/projects').default
      injectReducer(store, { key: 'projects', reducer })

      callback(null, {
        component: require('./containers/ProjectsViewContainer').default
      })
    }, 'projects')
  },

  getChildRoutes (partialNextState, callback) {
    require.ensure(['./containers/ProjectsViewContainer'], function (require) {
      // Don't want to repeat this
      const reducer = require('./modules/projects').default
      injectReducer(store, { key: 'projects', reducer })
      callback(null, [
        { path: ':id', component: require('./containers/ProjectOverviewContainer').default }
      ])
    })
  },

I'd like to remove the duplicate injection of the reducer but I'm not sure how to do this and keep it working. I saw similar issues #1049 and #797 but they are not quite the same. Perhaps I'm going about it the wrong way with getIndexRoute and should be using it in conjunction with getComponent somehow?

Awesome starter kit - really appreciate the hard work you guys put in

nicklee1990 avatar Jan 01 '17 15:01 nicklee1990

I think I managed to solve this by doing the following:

getComponent(location,cb) {
    require.ensure([], function (require) {
      /*  Add the reducer to the store on key 'projects'  */
      const reducer = require('./modules/projects').default
      injectReducer(store, { key: 'projects', reducer })

      cb(null, require('./containers/ProjectsLayout').default)
    }, 'projects')
  },

  getIndexRoute (partialNextState, callback) {
    require.ensure([], function (require) {
      callback(null, {
        component: require('./containers/ProjectsViewContainer').default
      })
    })
  },

  getChildRoutes (partialNextState, callback) {
    require.ensure(['./containers/ProjectsViewContainer'], function (require) {
      callback(null, [
        { path: ':id', component: require('./containers/ProjectOverviewContainer').default }
      ])
    })
  },

Where ProjectsLayout is just export default ProjectsLayout = ({ children }) => children. From what I can tell it works nicely but not sure if it's the "right" way

nicklee1990 avatar Jan 01 '17 16:01 nicklee1990

This helped me a lot, thank you! 👍

popaulina avatar May 13 '17 19:05 popaulina