33

I am relatively new to reacts and I'm trying to figure out how to get React router to work. I've got a super simple test app that looks like this:

import React from 'react';
import ReactDOM from 'react-dom';

import {BrowserRouter as Router, Route, Switch, IndexRoute, Link} from 'react-router-dom';

const Home = () => <h1><Link to= "/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const Test = () => (
  <Router>
    <Switch>
    <Route path ="/" component = {Home} />
    <Route path ="/about" component = {About} />
    </Switch>
  </Router>
)

ReactDOM.render(<Test />, document.getElementById('app'));

when I run the app the home component loads without any trouble, and when I click the "Click Me" link the url changes to localhost/about, however nothing happens. If I click refresh I get a "Cannot GET /about." Clearly I am doing something wrong but I haven't been able to figure out what. I am also using Webpack.

WebbH
  • 1,216
  • 1
  • 8
  • 21
  • Are there any messages in the console? It may be an issue with the `About` component and not the router itself. Also, try to put the `About` component on the */* path to see what happens. – gretro Apr 17 '17 at 18:23
  • RE: Cannot GET /about: Consider using [create-react-app](https://github.com/facebookincubator/create-react-app). It's facebook blessed and makes the server part of this work out of the box in development, among many other development niceties. Without it you need to manage routing everything to index.html yourself, or use the hash router in react-router. – Alex Guerra Apr 17 '17 at 18:27

7 Answers7

66

You need to use an exact path for / otherwise it will also match /about.

<Route exact path="/" component={Home} />

As mentioned in the comments, for something this simple I would suggest using Create React App which will make sure your server code and your webpack settings are all correct. Once you use create-react-app you'll just need to use npm to install the react router v4 package, and then put your code above into the App.js file and it should work. There are some small changes to your code to get it to work with create-react-app as can be seen below:

// App.js
import React from 'react';

import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';

const Home = () => <h1><Link to="/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
    </Switch>
  </Router>
)

export default App;

The quick start instructions from React Router V4 documentation will tell you pretty much the same as I just explained.

Todd Chaffee
  • 6,258
  • 28
  • 39
33

If you're running from localhost you need to add historyApiFallback: true to your webpack.config file

VineFreeman
  • 675
  • 6
  • 12
8

if Adding exact Don't resolve issue, i have replaced this with

  <Route exact path="/" component={App} />
  <Route path="/login" component={Login} />
  <Route path="/register" component={Register} />

This one

  <Route exact path="/"> <App /> </Route>
  <Route path="/login"> <Login /> </Route>
  <Route path="/register"> <Register /> </Route>

putting component as Route Child solves my page routing i hope it helps someone else too

Shashank Shekhar
  • 3,402
  • 2
  • 38
  • 49
Hanzla Habib
  • 1,707
  • 15
  • 18
4

You can also solve this issue by keeping the default Route always at the end

<Route path ="/about" component = {About} />

<Route path="/" component={Home} /> // Always at the end

No need to put exact keyword

4

While using Switch we need to keep in mind that we specify the routes to be from most specific to most generic. In your case, you have specified "/" before "/about". So every time react is looking for "/about" but going down <Route "/" satisfies for "/about" as well (because "/about" is sub-route of "/") So use: "/about" before "/"

This way you can omit exact as well

import React from 'react';
import ReactDOM from 'react-dom';

import {BrowserRouter as Router, Route, Switch, IndexRoute, Link} from 'react-router-dom';

const Home = () => <h1><Link to= "/about">Click Me</Link></h1>
const About = () => <h1>About Us</h1>

const Test = () => (
  <Router>
    <Switch>
        <Route path ="/about" component = {About} />
        <Route path ="/" component = {Home} />
    </Switch>
  </Router>
)

ReactDOM.render(<Test />, document.getElementById('app'));
2

Maybe it can help someone. I forgot to use the proper history, instead of using the Router I was using the BrowserRouter which ignores the property history={...} to use its own. I was trying to redirect the page with my manually created history but BrowserRouter was using its own one.

Alex
  • 1,064
  • 9
  • 16
1

Here is another way this can happen. It is a stupid mistake but that was the issue in my case.

My problem was an import error. Initially, I had the following import :

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

I decided to move the BrowserRouter component to a higher level but while removing the no longer user Router component, my imports became like this :

import { BrowserRouter as Switch, Route } from 'react-router-dom';

So, effectively, I ended up removing the Switch component and aliasing BrowserRouter as Switch.

It was normal that Switch was no longer working as expected.

EmirDev
  • 87
  • 5