React Router Switch and exact path

Although in your case you can get the same effect using exact but it may not always be the case. However in cases where one of your Route contains nested route, if you have exact Route at the top level, you cannot make use of the nested Routes.

Switch in the above case serves the purpose since it renders the first match only

For example,

Say Home route contains nested Routes like

const Home = (props) => (
     <div>
          <Route path="/dashboard" component={Dashboard}/>
          <Route path="/layout" component={Layout}/>
     </div>
)

So now if you write

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

and when you visit /dashboard. That Dashboard component cannot be rendered since no Route matches with /dashboard at the top level.

In order to make the example run correctly, you can make use of Switch and reorder the routes so that the paths that are prefixes to other paths are at the end

<Switch>
  <Route path="/a" component={A} />
  <Route path="/b" component={B} />
  <Route path="/" component={Home} />
</Switch>

Let me put out the distinct features of Route, exact and Switch:

  • Route does the partial matching. Route's path matches inclusively (matching many).

  • exact removes partial matching. It might match more than one routes, in case we are using wild cards in the routes.

  • Switch renders only the route that first matches. Switch path matches exclusively (matching only one).

To explain in detail, I want to illustrate how the route matching works with and without exact. Let's suppose we have the below code and we are not using exact.

how-route-matches-without-exact

So, if we visit /pagetwo URL, Route will do the partial matching and will render both the routes. Let's see how it happens. In the below illustration, we are looking at the address bar and the path we are navigating to (extracted path) and what route(s) is(are) getting matched. So, Route will render a route when extractedPath.contains(path-in-our-Route-declaration) evaluates to be true.

how-path-gets-matched-1

how-path-gets-matched-2

Hope that clarifies how Route works behind the scene. To avoid this partial matching, we use exact. The use of exact resolves the problem until we encounter some special cases. Suppose we have two routes like:

  • /users/create
  • /users/* (wildcard in the route).

In the above case, the exact will match both the routes. So, to resolve such issues, we can use Switch. It renders only one route and whatever route is matched first. So, here the order in which you are defining your routes matters.