Home > Net >  React Router Dom, render a component only for some routes
React Router Dom, render a component only for some routes

Time:06-20

I have a React application with React Router Dom v6 and trying to render the Nav component when the path does NOT match the root "/" but I'm having trouble getting it to work. This is my code:

import { BrowserRouter as Router, Routes, Route, matchPath } from "react-router-dom";
import Nav from "./components/Nav/Nav";
import Home from "./components/Home/Home";
import Contributors from "./components/Contributors/Contributors";

const App = () => {
    const match = matchPath({ path: "/", end: true }, "/");
    return (
        <Router>
            {!match ? <Nav /> : null}
            <Routes>
                <Route path="/" exact element={<Home />} />
                <Route path="/contributors" element={<Contributors />} />
            </Routes>
        </Router>
    );
}

export default App;

How should I fix this?

CodePudding user response:

Quick Solution:

You could simply do like below, adding the Nav where you want. I'm not sure if you can know the path in App, since it's not wrapped inside the Router.

import { BrowserRouter as Router, Routes, Route, matchPath } from "react-router-dom";
import Nav from "./components/Nav/Nav";
import Home from "./components/Home/Home";
import Contributors from "./components/Contributors/Contributors";

const App = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" exact element={<Home />} />
                <Route path="/contributors" element={<><Nav /><Contributors /></>} />
            </Routes>
        </Router>
    );
}

export default App;

Improvement:

And if you want to take it further, instead of doing like above, you could set up a Layout component, like this:

import { Outlet } from "react-router-dom";
import Nav from "../Nav/Nav";

const Layout () => {
  return (
    <>
      <Nav />
      <Outlet />
    </>
  );
};

export default Layout;

And render the routes where you want the Nav trough the Layout:

import { BrowserRouter as Router, Routes, Route, matchPath } from "react-router-dom";
import Home from "./components/Home/Home";
import Contributors from "./components/Contributors/Contributors";
import Layout from "./components/Layout/Layout";

const App = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" exact element={<Home />} />
                <Route element={<Layout />}>
                   <Route path="/contributors" element={<Contributors />} />
                </Route>
                
            </Routes>
        </Router>
    );
}

export default App;

CodePudding user response:

You need to remove the <Router> from your App component and instead wrap the component in your index.tsx file like this:

<Router>
 <App />
</Router>

You can then do the rest as you already did but with the pathname as an argument of the matchPath function:

const App = () => {
  const { pathname } = useLocation();
  const match = matchPath({ path: "/", end: true }, pathname);
  • Related