MonkeyBonkey MonkeyBonkey - 2 days ago 7
React JSX Question

Adding multiple routes with react-router in an electrode app does nothing

I'm getting started with Walmart's react/redux/react-router/isomorphic boilerplate called electrode and I'm having trouble adding multiple routes. When I add the 2nd route it seems to do nothing and linking and pushing to the other routes does not change the page.

http://www.electrode.io/docs/get_started.html

https://github.com/electrode-io/electrode-redux-router-engine

Here's what the single route in the boilerplate looked like

// routes.jsx
import React from "react";
import {Route} from "react-router";
import Home from "./components/home";

export const routes = (
<Route path="/" component={Home}/>
);


and here's what I changed it to

import React from "react";
import {Route, IndexRoute} from "react-router";
import Home from "./components/home";
import Foo from "./components/foo";

export const routes = (
<Route path="/" component={Home}>
<Route path="/foo" component={Foo}/>
</Route>
);


I couldn't put the routes side by side because that gave me an error saying that jsx can't have two elements side-by-side so I had to nest it. The react router examples I see online seem to assume a root app component. Looking at the electrode router redux sample, they set the root component to "Page". What is the "Page" component? My questions are


  1. Why doesn't my 2nd route work?

  2. Should I be using an IndexRoute?

  3. Do I need to create a root component for the root route? If so what does that component look like?



Here's the app.jsx code

//
// This is the client side entry point for the React app.
//

import React from "react";
import {render} from "react-dom";
import {routes} from "./routes";
import {Router} from "react-router";
import {createStore} from "redux";
import {Provider} from "react-redux";
import "./styles/base.css";
import rootReducer from "./reducers";

//
// Add the client app start up code to a function as window.webappStart.
// The webapp's full HTML will check and call it once the js-content
// DOM is created.
//

window.webappStart = () => {
const initialState = window.__PRELOADED_STATE__;
const store = createStore(rootReducer, initialState);
render(
<Provider store={store}>
<Router>{routes}</Router>
</Provider>,
document.querySelector(".js-content")
);
};

Answer

A few things...

You can avoid the "side by side jsx" warning by wrapping your routes in an empty route or returning an array.

// return nested routes
return (    
  <Route path="/">
    <Route path="foo" component={Foo}/>
    <Route path="bar" component={Bar}/>
  </Route> 
)

// return array, must use keys
return [
  <Route key="foo" path="/foo" component={Foo}/>,
  <Route key="bar" path="/bar" component={Bar}/>
]

If you want to nest routes, you need to give way to the child component by adding {this.props.children} to the parent component's render.

If you want truly separate routes that are not nested, it shouldn't be a child of the first route. I don't think adding an IndexRoute would provide any benefit unless you want some UI that is top level for all routes (like rendering a header, sidebar, etc).

Comments