Cassidy
Cassidy

Reputation: 3408

React Router not switching to non-base routes

I'm setting up React Router in a project that was previously using Reach Router.

Before, the routes looked like this with Reach:

import { Router } from '@reach/router';

...

<Router>
      {anon ? <AnonHomepage /> : <Homepage />}
      <Explore path="explore/:category" />
</Router>

And then, switching to React Router, I have my file set up like this:

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

...

<BrowserRouter>
      <Switch>
        {anon ? (
          <Route path="/" component={AnonHomepage} />
        ) : (
          <Route path="/" component={Homepage} />
        )}
        <Route
          path="/explore/:category"
          component={Explore}
        />
      </Switch>
</BrowserRouter>

But, the router keeps only showing the AnonHomepage and/or the Homepage in that / route, never the /explore (or any other) route anymore. What am I doing wrong? How can I make it use the correct components instead of always showing the base route's components?

Upvotes: 2

Views: 283

Answers (2)

Ross Hunter
Ross Hunter

Reputation: 141

Short answer: you need to pass the Boolean prop exact to your root route, like so:

<Switch>
  <Route exact path='/' component={YourComponent} />
  <Route path='path/to/other/component' component={OtherComponent) />
</Switch>

Explanation: Checkout the documentation on the <Switch> component here. Switch renders only the first route whose path prop matches the current location. Essentially, when React Router receives a new navigation and looks for a Route to match it to, it tests the navigation path with the Route path as if the Route path were a regular expression. Because every navigation path on your website includes the root path, path='/' will match every possible navigation. Since the root Route is the first route listed, it is the first route Switch will test, and since that test will necessarily result in a match, Switch never tests the other routes, it just renders the root component.

Adding the exact prop to a route does what you would expect--it prevents Switch from detecting a match unless the path in the Route is exactly the navigation path. So '/root/other/folder' will not match '/' on a route whose exact prop is set, because '/' is not exactly equal to '/root/other/folder'.

Upvotes: 2

Emma Hamilton
Emma Hamilton

Reputation: 71

You can use the exact prop on the Route

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

...

<BrowserRouter>
      <Switch>
        {anon ? (
          <Route exact path="/" component={AnonHomepage} />
        ) : (
          <Route exact path="/" component={Homepage} />
        )}
        <Route
          path="/explore/:category"
          component={Explore}
        />
      </Switch>
</BrowserRouter>

Upvotes: 3

Related Questions