Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router Switch and exact path

I have read this document about react-router Switch

I understand the definition about Switch and Route

But still couldn't understand some points

If I want to pick only one Route to render we use Switch like this

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

The point I can't understand is I can get same effect without Switch

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

So why do we use Switch ? When do we need to use Switch?


I found a situation that need to use Switch

If I want to render a specific component when no path match

we need to wrap Route in Switch like this

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

Am I right ?

like image 307
Anymore Avatar asked Aug 22 '18 06:08

Anymore


2 Answers

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.

like image 62
Shraddha Avatar answered Sep 29 '22 03:09

Shraddha


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>
like image 38
Shubham Khatri Avatar answered Sep 29 '22 04:09

Shubham Khatri