In React Router v5 and earlier, the exact
prop was used to ensure that a route only matched the exact URL path. If you didn’t use exact
, React Router would match any route that partially matched the URL. This could lead to unexpected matches and render the wrong component for a given path.
In React Router v6 and later, the exact
prop is no longer necessary, as all routes now match exactly by default.
However, if you are working with React Router v5 or earlier, understanding when and how to use exact
is crucial to avoid these unexpected route matches.
What Is the Problem?
In React Router v5 and earlier, when you define a route without the exact
prop, the route will match any URL that starts with the path defined in the path
attribute. This can lead to unexpected behavior if multiple routes overlap.
Example of Issue (React Router v5 or earlier):
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} /> {/* Unexpected match without 'exact' */}
<Route path="/about" component={About} />
</Router>
);
}
export default App;
Issue:
- The first
<Route path="/" component={Home} />
will match any URL that starts with/
, which means it will also match/about
. This causes theHome
component to be rendered on/about
, even though/about
is supposed to render theAbout
component.
Solution: Use exact
Prop to Avoid Unintended Matches
To ensure that the Home
route only matches exactly /
and not any subpath like /about
, you need to use the exact
prop in React Router v5 or earlier.
Corrected Example (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 exact path="/" component={Home} /> {/* Exact match for '/' */}
<Route path="/about" component={About} />
</Router>
);
}
export default App;
Explanation:
- By adding
exact
to theRoute
for theHome
component, the route will only match when the path is exactly/
and not any subpath. - The route for
/about
will work as expected and render theAbout
component when navigating to/about
.
How React Router v6 Handles Exact Matches:
In React Router v6 and later, the exact
prop is no longer needed because all routes match exactly by default. If you’re using React Router v6, you don’t need to worry about specifying exact
for matching routes. The behavior has changed, and the router will no longer match partial paths.
Example in React Router v6 (No exact
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 />} /> {/* Exact match by default */}
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;
Explanation:
- In React Router v6, the
exact
prop is unnecessary. Routes will match exactly by default, so the route for/
won’t match/about
unless explicitly defined.
Key Points to Remember:
- In React Router v5 (and earlier):
- Use the
exact
prop to ensure a route matches only the exact URL and not any subpaths. - If you don’t use
exact
, the route will match any URL that starts with the given path (e.g.,/
will match both/
and/about
).
- Use the
- In React Router v6 (and later):
- All routes match exactly by default. The
exact
prop is not required and can be omitted.
- All routes match exactly by default. The
- Order of Routes Matters:
- Always define your most specific routes first (e.g.,
/about
), and your catch-all routes (e.g.,/
) last to prevent them from matching prematurely.
- Always define your most specific routes first (e.g.,
Example of Unexpected Behavior Without exact
(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} /> {/* Unexpected match */}
<Route path="/about" component={About} />
</Router>
);
}
export default App;
Issue:
- When navigating to
/about
, theHome
component is displayed because theRoute
for/
matches all paths, including/about
. - This behavior is unexpected, and to fix it, we would need to add the
exact
prop to the/
route.
Corrected Example with exact
(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 exact path="/" component={Home} /> {/* Exact match for '/' */}
<Route path="/about" component={About} />
</Router>
);
}
export default App;