![]()
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 theHomecomponent to be rendered on/about, even though/aboutis supposed to render theAboutcomponent.
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
exactto theRoutefor theHomecomponent, the route will only match when the path is exactly/and not any subpath. - The route for
/aboutwill work as expected and render theAboutcomponent 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
exactprop is unnecessary. Routes will match exactly by default, so the route for/won’t match/aboutunless explicitly defined.
Key Points to Remember:
- In React Router v5 (and earlier):
- Use the
exactprop 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
exactprop 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, theHomecomponent is displayed because theRoutefor/matches all paths, including/about. - This behavior is unexpected, and to fix it, we would need to add the
exactprop 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;
