0

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 Answers2

2

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

Community
  • 1
  • 1
hansn
  • 1,631
  • 1
  • 13
  • 31
  • I'm not sure if that is really the problem. In my understanding of client side routing the router would prevent the actual http request to the server and instead render the component that is specified in the 'routing table'. Isn't that how react-router works? Sending the same data on every request seems more like a hack to me. – Nils Schikora May 08 '16 at 06:37
  • @NilsShikora That is true when you are navigating your application using react-routers `` element. However if you are accessing `/register` directly, your server is obviously going to get the request and has to know how to deal with it. – hansn May 08 '16 at 07:09
  • Oh well I havent thought of that. Another point I need to make clear, thanks. But the react-router fails in either way. I'm using Register in a component and the transition fails. – Nils Schikora May 08 '16 at 07:19
  • What do you mean the transition fails? Also try `to="register"`, note the missing slash. Dno if it will work – hansn May 08 '16 at 07:21
  • By that I mean the server responds 404 even if I click the link in the correctly rendered Home component. Changing the link to ````to="register"```` did not make any changes. – Nils Schikora May 08 '16 at 07:24
  • Can we see this component? As far as I know s do not generate http requests, so you shouldn't get a 404. – hansn May 08 '16 at 07:37
  • What component would you like to see? The linked to or the one that contains the ? – Nils Schikora May 08 '16 at 07:44
  • The one that contains the link. – hansn May 08 '16 at 07:51
  • Sure it's the Navigation component, that is rendered inside the App. I'll edit it into my post. – Nils Schikora May 08 '16 at 08:11
1

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.

Kairxa
  • 21
  • 2