![]()
In React Router v5 and earlier, it was essential to wrap your route definitions with the <Switch> component. The <Switch> component ensures that only one route is rendered at a time. Without <Switch>, React Router would render all matching routes, which could lead to unexpected behavior, as more than one component would be displayed simultaneously.
In React Router v6, the <Switch> component was replaced with <Routes>, which automatically behaves like the old <Switch>, ensuring only one route is rendered.
However, for React Router v5 and earlier, forgetting to add <Switch> can cause multiple routes to render when only one should be displayed.
Common Issue:
If you forget to add <Switch>, React Router may match multiple routes, and all of them could be rendered simultaneously, leading to visual confusion and unexpected behavior in your app.
Example of Issue (React Router v5):
import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
export default App;
Issue:
- In the code above, without the
<Switch>wrapper, both routes (/and/about) can be matched and rendered simultaneously if they overlap. For example, visiting/aboutmight render both theHomeandAboutcomponents because the router doesn’t know which one to prioritize.
Solution: Add <Switch> to Ensure Only One Route is Rendered
To fix this, wrap your routes with the <Switch> component. The <Switch> ensures that only the first route that matches the current URL is rendered.
Corrected Example with <Switch> (React Router v5):
import React from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
export default App;
Explanation:
- The
<Switch>component ensures that only one route will be rendered at a time. It will stop looking for further matches once it finds the first match. - The
exactprop is used on the/route to make sure it only matches the home route (/) and not any other routes that start with/(like/about).
React Router v6: No Need for <Switch>
In React Router v6, the Switch component was replaced by the <Routes> component, which automatically handles the behavior of rendering only the first matching route.
In v6, you no longer need to use <Switch> or exact. All routes now match exactly by default.
Example in React Router v6 (No <Switch> Needed):
import React from 'react';
import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;
Explanation:
<Routes>behaves like the old<Switch>, ensuring that only one route is matched and rendered.- There is no need for the
exactprop because all routes are matched exactly by default.
Key Points to Remember:
- In React Router v5 and earlier:
- Always wrap your routes in a
<Switch>to ensure only one route is rendered at a time. - Use the
exactprop to ensure that the route for/only matches the home route and does not interfere with other routes like/about.
- Always wrap your routes in a
- In React Router v6:
- The
<Switch>component is replaced by<Routes>, which automatically ensures that only one route is rendered. - There is no need to use the
exactprop anymore as routes now match exactly by default.
- The
- Route Order:
- In both v5 and v6, the order of routes matters. Place the most specific routes first and the catch-all routes last to prevent them from matching prematurely.
Example of Unexpected Behavior Without <Switch> (React Router v5):
import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
{/* Missing <Switch> */}
<Route path="/" component={Home} /> {/* This may match /about as well */}
<Route path="/about" component={About} />
</Router>
);
}
export default App;
Issue:
- Without
<Switch>, both theHomeandAboutcomponents could be rendered when navigating to/about, which is not the desired behavior.
Corrected Example with <Switch> (React Router v5):
import React from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
export default App;
