Not using exact in  leading to unexpected matches

Loading

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 the Home component to be rendered on /about, even though /about is supposed to render the About 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 the Route for the Home 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 the About 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:

  1. 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).
  2. In React Router v6 (and later):
    • All routes match exactly by default. The exact prop is not required and can be omitted.
  3. 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.

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, the Home component is displayed because the Route 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;

Leave a Reply

Your email address will not be published. Required fields are marked *