I`ve been following an e-commerce tutorial and building on top of it. Im new to React and React Router Dom. I've set a dynamic path for individual product pages, and now i' trying to add some new paths i.e. contact, about, etc.. If I add the new paths above the dynamic path they are rendered properly, but if I place the routes under the one with the dynamic path, for example the /hello, they won't render. Is this normal behaviour??
<Router>
<div>
<Navbar totalItems={cart.total_items} />
<Switch>
<Route exact path="/">
<Home products={products} handleAddToCart={handleAddToCart} fetchProduct={fetchProduct} />
</Route>
<Route exact path="/checkout">
<Checkout cart={cart} order={order} handleCaptureCheckout={handleCaptureCheckout} error={errorMessage} refreshCart={refreshCart} />
</Route>
<Route exact path="/cart">
<Cart
cart={cart}
handleUpdateCartQuantity={handleUpdateCartQuantity}
handleRemoveFromCart={handleRemoveFromCart}
handleEmptyCart={handleEmptyCart}
/>
</Route>
<Route exact path="/contact">
<Contact />
</Route>
<Route exact path="/:id">
<Details product={product} handleAddToCart={handleAddToCart} />
</Route>
<Route exact path="/hello">
<h1>Hello World</h1>
</Route>
</Switch>
</div>
<Router>
CodePudding user response:
Yes, this behavior is completely normal, and expected. Recall that the Switch
component "Renders the first child <Route>
or <Redirect>
that matches the location." This means that in the Switch
component path order and specificity matter!
A path "/hello"
is more specific than "/:id"
, so depending on route order may or may not be matched first. Or in other words, "/hello"
can always be matched to "/:id"
, but not always the other way around.
You should always order the routes from more specific paths to less specific paths, and if done correctly there should be a near zero need for the exact
prop.
"/hello"
is more specific than "/:id"
which is more specific than "/"
.
<Switch>
<Route path="/checkout">
<Checkout ... />
</Route>
<Route path="/cart">
<Cart ... />
</Route>
<Route path="/contact">
<Contact />
</Route>
<Route path="/hello">
<h1>Hello World</h1>
</Route>
<Route path="/:id">
<Details ... />
</Route>
<Route path="/">
<Home ... />
</Route>
</Switch>
If you had a nested "/contact/add"
route for example, this is more specific than "/contact"
and should be listed higher/before in the Switch
.
CodePudding user response:
Try removing the exact from the Route.
<Route exact path="/:id">
to:
<Route path="/:id">