No routes matched location "/cart" in router router dom v 6

Viewed 2905

When I console.log qty (in the code below), I see No routes matched location "/cart" (from browser console) instead of value of qty. In react-router-dom v5 everything works well by passing location as props to the component, but that isn't working in v6. The following block of code work in router-dom v5:

export function CartScreen({ match, location, history}) {
    const qty = location.search ? Number(location.search.split("=")[1]): 1

    console.log('qty:', qty)


    return (
        <div>
            <h1>Add to CART</h1>
        </div>
    )
}

Add to Cart Handler:

const addToCartHandler = () =>{
        history(`/cart/${match.id}?qty=${qty}`)
    }

<Button type='button' onClick={addToCartHandler} > Add To Cart </Button>

However, the above code is no valid in router-dom v6, so I try to achieve the same result by changing it to the one below(but it is not working):

const CartScreen = () => {
    const match = useParams()
    const location = useLocation();
    const productID = match.id
    const qty = location.search ? Number(location.search.split("=")[1]): 1

    console.log('qty:', qty)


    return (
        <div>
            <h1>Add to CART</h1>
        </div>
    )
}

App.js

function App() {
    return (
    <Router>
      <Routes>
          <Route path='/cart/:id?' element={<CartScreen/>} />
      </Routes>
    </Router>
  );
}

export default App;

The main issue that is with the the way I used location in router dom v 6.

2 Answers

react-router-dom v6 doesn't use REGEX in paths like v5 did. If you want to use "optional" path segments then you need to render an explicit route/path for each you want to match.

<Router>
  <Routes>
    <Route path="/cart/:id" element={<CartScreen />} />
    <Route path="/cart" element={<CartScreen />} />
  </Routes>
</Router>

You can still use the location object to access the search queryString.

const { search } = useLocation();
const qty = search ? Number(search.split("=")[1]) : 1;

But the code is assuming the "qty" is the first search parameter.

v6 introduced a useSearchParams hook for accessing the queryString.

const [searchParms] = useSearchParams();
cont qty = Number(searchParms.get("qty"));

Edit no-routes-matched-location-cart-in-router-router-dom-v-6

Code:

const CartScreen = () => {
  const { id } = useParams();
  const { search } = useLocation();
  const [searchParms] = useSearchParams();

  const productID = id;
  const qty = search ? Number(search.split("=")[1]) : 1;

  console.log({ productID, qty, qtyParam: Number(searchParms.get("qty")) });

  return (
    <div>
      <h1>Add to CART</h1>
    </div>
  );
};

Console log: {productID: "123", qty: 23, qtyParam: 23}

For the addTo cart handler you need to use the useNavigate() instead of the history since is no longer required in react-router dom v6

Related