Search code examples
javascriptreactjsdjango-rest-frameworkreact-router-dom

Why my id and empty path route not working


My route with id and no path are not working but others are fine.

<Route path='/listings:id' Component={ListingDetail} />
<Route Component={NotFound} />

These are not working they just show my HOC component not showing requested components under my HOC when I remove "id" from path '/listings:id' and path in <Route Component={NotFound} /> then they work fine.

For example, if I put on browser it should route to path='/listings:id'

"http://localhost:3000/listings/afsdf"

and for same if I put path that does not exist

"http://localhost:3000/ahkdhfsad"

it should route to Component={NotFound}

import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './containers/Home';
import About from './containers/About';
import Contact from './containers/Contact';
import Listings from './containers/Listings';
import ListingDetail from './containers/ListingDetail';
import SignIn from './containers/SignIn';
import SignUp from './containers/SignUp';
import NotFound from './components/NotFound';
import Layout from "./hocs/Layout";

const App = () => {
  return (
    <>
      <Router>
        <Layout>
          <Routes>
            <Route path='/' Component={Home} />
            <Route path='/about' Component={About} />
            <Route path='/contact' Component={Contact} />
            <Route path='/listings:id' Component={ListingDetail} />
            <Route path='/listings' Component={Listings} />
            <Route path='/signin' Component={SignIn} />
            <Route path='/signup' Component={SignUp} />
            <Route Component={NotFound} />
          </Routes>
        </Layout>
      </Router>
    </>
  );
}

export default App;

Solution

  • Issues

    • Partial path segments are not valid in React-Router v6. The route path "/listings:id" will match the literal string value "/listings:id". If you are wanting to match "/listings/afsdf" then separate ":id" into it's own path segment, e.g. "/listings/:id".

    • The "not found" route still needs a path. Specify path="*" if you want a "catch-all" route.

    • Not a breaking issue, but the Route component's Component prop is only meant to be used in Data routers (created using createBrowserRouter, createHashRouter, etc).

      IMPORTANT

      You should only opt into the Component API for data routes via RouterProvider. Using this API on a <Route> inside <Routes> will de-optimize React's ability to reuse the created element across renders.

      You should instead use the element prop and pass the routed content as JSX.

      See Route: element/Component for more details.

    Solution

    • Update route path path="/listings:id" to path="/listings/:id".
    • Render NotFound on path path="*".
    • Use the element prop and pass components as JSX.
    const App = () => {
      return (
        <Router>
          <Layout>
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="/about" element={<About />} />
              <Route path="/contact" element={<Contact />} />
              <Route path="/listings/:id" element={<ListingDetail />} />
              <Route path="/listings" element={<Listings />} />
              <Route path="/signin" element={<SignIn />} />
              <Route path="/signup" element={<SignUp />} />
              <Route path="*" element={<NotFound />} />
            </Routes>
          </Layout>
        </Router>
      );
    };