0
votes

I'm stuck creating a single page app using react, redux, react-router and react-redux-router bindings.

The route http://localhost:3001/register is simply not matched by the router and Cannot GET /register is returned to the browser because the server obviously doesn't know the route. I'm relatively new to the react-redux stack and may be missing something pretty basic.

Edit: The IndexRoute is working and is displaying the Home-Component inside the App-Compontent.

Edit2: I'm not using server side rendering and am developing using the webpack-dev-server.

But here are the related code-snippets so far:

entry.js

const store = createStore( 
    reducer, //from reducers.js
    applyMiddleware(routerMiddleware(browserHistory))
);

const history = syncHistoryWithStore(browserHistory, store);

render(
    <Provider store={store}>
        <Router history={history} routes={routes} />  //routes from routes.js
    </Provider>,
    document.getElementById('app')
 );

reducers.js

const rootReducer = combineReducers({
    RegisterForm,
    routing: routerReducer //provided by react-router-redux
});

export default rootReducer;

routes.js

const routes = (
    <Route path='/' component={App}>
        <IndexRoute component={Home} />
        <Route name='register' path='register' component={RegisterForm} />
    </Route>
);

export default routes;

Navigation.jsx (rendered inside App.jsx)

import React from 'react';
import {Link} from 'react-router';

export default class Navigation extends React.Component {
  render() {
    return (
      <div className="mdl-layout mdl-js-layout mdl-layout--fixed-header">

        <header className="mdl-layout__header">
          <div className="mdl-layout__header-row">
            <span className="mdl-layout-title">there!</span>
            <div className="mdl-layout-spacer"></div>
            <nav className="mdl-navigation mdl-layout--large-screen-only">
              <Link className="mdl-navigation__link" to="/">Home</Link>
              <Link className="mdl-navigation__link" to="register">Register</Link>
            </nav>
          </div>
        </header>

        <div className="mdl-layout__drawer">
          <span className="mdl-layout-title">there!</span>
          <nav className="mdl-navigation">
            <Link className="mdl-navigation__link" to="/">Home</Link>
            <Link className="mdl-navigation__link" to="register">Register</Link>
          </nav>
        </div>

        <main className="mdl-layout__content">
          <div className="page-content">
            {this.props.children}
          </div>
        </main>

      </div>
    );
  }
}

Maybe it is obvious to someone, what I am missing here. If you need more of the code please let me know.

2
Are you using the --history-api-fallback flag when booting up webpack-dev-server?Bryan Fillmer
devServer: { historyApiFallback: true } is set in the webpack.config.jsNils Schikora
Magically the routing is now working after I upgraded all packages to their latest versions.Nils Schikora

2 Answers

2
votes

As you say, the problem is that your backend does not know how to handle requests to /register. The solution is to tell your backend to return the react application (same as requests to /) on such requests.

If you are developing with pure webpack-dev-server I'm not 100% sure what's the best way to do this, but you can take a look at the answer here which will probably work: Stating directive templateUrl relative to root

1
votes

You can use hashHistory instead of browserHistory. It's written in react-router's documentation.

Of course, you will need to configure the Link's to props so it will redirect properly according to the needs of hashHistory. Later on, when you are back using browserHistory, you need to reconfigure those links again.