2

I'm using react, redux and react router amoung others to build and example app.

I'm trying to load asynchronously different parts of my application. I've divided my app in ducks and I'm following this example https://github.com/insin/react-examples/tree/master/code-splitting-redux-reducers

But I'm getting this error:

Uncaught Invariant Violation: The root route must render a single element

When trying to get async component with getComponent method of react router. I'm using: react-router 2.0.1

My routes:

export default function configureRoutes(reducerRegistry) {
  return(
    <Route>
      <Route component={Landing}>
        <Route path='/login' component={Login}/>
        <Route path='/register' component={Register}/>
      </Route>
            <Route path="admin" getComponent={(location, cb) => {
                require.ensure([], require => {
                    cb(null, require('./containers/admin'))
                })
            }}/>
      <Route component={App}>
        <Route  path='/' component={Home} />
      </Route>
    </Route>
)}

My component

class Admin extends Component {
  componentDidMount() {
    this.props.load()  
  }
  render() {
    const { message, isFetching } = this.props
    return (
      <div>
        <p>{message}</p> 
        <p>This module was loaded via chunk </p>
        {loading && <p>Doing some fake loading ...</p>}
      </div>
    )  
  }  
}

Admin.propTypes = {
  message: PropTypes.string.isRequired,
  isFetching: PropTypes.bool.isRequired,
  load: PropTypes.string.isRequired
}

const mapStateToProps = state => state.admin

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ load }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(Admin)

Does anyone have the same error? any ideas? Anyone have something similar working?

Thanks community!

Update: Added index.js for clarity

import configureRoutes from './routes'
import configureStore from './store/configureStore'
import coreReducers from './modules/core'
import ReducerRegistry from './reducer-registry'

var reducerRegistry = new ReducerRegistry(coreReducers)

// Configure hot module replacement for core reducers
if (process.env.NODE_ENV !== 'production') {
  if (module.hot) {
    module.hot.accept('./modules/core', () => {
      var nextCoreReducers = require('./modules/core')
      reducerRegistry.register(nextCoreReducers)
    })
  }
}

const routes = configureRoutes(reducerRegistry)
const store = configureStore(reducerRegistry)

render(
  <I18nextProvider i18n={i18n}>
    <Provider store={store}>
      <Router history={browserHistory} routes={routes} />
    </Provider>
  </I18nextProvider>,
  document.getElementById('root')
)
9
  • The error is very specific, it's not about the async part.. look at the route config in the example you're following. Notice how all the Routes have paths? github.com/insin/react-examples/blob/master/… Commented Mar 11, 2016 at 17:15
  • And your root path / has to be the root, actually.. Commented Mar 11, 2016 at 17:15
  • Webpack versions I'm using on dev webpack 1.12.13 webpack-dev-middleware 1.5.1 webpack-hot-middleware 2.6.4 Commented Mar 11, 2016 at 17:17
  • Your route config is incorrect, it has nothing to do with webpack. Commented Mar 11, 2016 at 17:18
  • @azium I don't know if I get what u are saying. My Route also have a path pointing to admin (i've miss the '/' but it throws the same error if I add it) Commented Mar 11, 2016 at 17:22

1 Answer 1

2

I think your root <Route> is missing the component field.

You need to specify either component or getComponent for every parent route, as this will be the component that the current child route’s component gets passed to as this.props.children.

Rather than

export default function configureRoutes(reducerRegistry) {
  return (
    <Route>

you want something like

export default function configureRoutes(reducerRegistry) {
  return (
    <Route component={App}>

In this case, you probably won’t need another App route below.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Dan. I managed to solve that error, moving the admin route inside the Landing route, so I understand that every route that uses getComponent should have a parent route with a component, as you said, to get passed to as this.props.children. But I'm still having a root route without component in order to wrap two different layouts with nothing in common. Do you think this is wrong approach?
Right now this.props.children of the parent route of admin, is undefined instead of having the async component requested. I think it is not related so I will open a new question.
I've already fixed the other error. If anyone is interested it is here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.