2

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.

C-Bizz
  • 624
  • 9
  • 25
  • Is this `CartScreen` rendered on a route with an `id` route param? Can you share how you are rendering the routes and routed components? – Drew Reese Dec 23 '21 at 01:53
  • Yes, I just updated the code, please check – C-Bizz Dec 23 '21 at 01:59
  • Ok, so `CartScreen` and the `id` route param should be fine. What is complaining about a missing `"/cart"` route? There also shouldn't be a trailing `"?"` on your path. – Drew Reese Dec 23 '21 at 02:11
  • Since id is optional in the path, when quantity of item is specified, just as it happens when a user clicks add to cart, the value of the quantity ought to be appended to the url. The qty is not being appended to '/cart'. The issue is with `react-router-dom location. I am not sure how to implement location.search in v6 – C-Bizz Dec 23 '21 at 02:23
  • @Drew Reese, I thought of better way to as the question and I updated the post again – C-Bizz Dec 23 '21 at 02:35

2 Answers2

4

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}

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thanks so much @Drew Reese. Your approach is very clear. But I encounter similar issue. when I click on add to cart button. Please check, I updated the post to include the addToCart button and handler – C-Bizz Dec 23 '21 at 03:52
  • Since react router 6 doesn't use regex, how do I handle the addToCart Handler to match with the add to cart path? I don't understand how the sperate add to cart part you spoke of will work with the handler – C-Bizz Dec 23 '21 at 04:07
  • @C-Bizz I would suspect it'd work similar to how it did in RRDv5. How does the `addToCartHandler` and button work in your RRDv5 implementation? – Drew Reese Dec 23 '21 at 04:31
  • 1
    Thanks you @Drew Reese. You have already answered the question I asked. I'll open another post for the url path Issue I'm having. – C-Bizz Dec 23 '21 at 18:02
0

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

Teddy
  • 21
  • 2