I’ve been trying to display a component in a different view from the parent component but what I get is the two components displayed in the same view, first parent component, and right below, child component when the Link
is clicked.
It’s a simple shopping cart (/cart
) and after clicking Pay
you should be redirected to checkout (/cart/checkout
) view, nevertheless the component
is being rendered right below.
I tried to set it up as a different route but the component
CheckoutData
won’t render unless I nest into its parent
Cart.js
I want to achieve this:
Cart
component is rendered, after clicking Pay
Link
you should be redirected to CheckoutData
component.
Cart.js
class Cart extends Component { // constructor and state removeItem(id) { // Axios call } componentDidMount() { //Axios call } render() { return ( <div> <ParentNav /> // content table <Link to="/cart/checkout"> Pay </Link> <Link to="/"> Go back </Link> </div> </div> <Footer /> </div> ); } }
CheckoutData.js
class CheckoutData extends Component { //constructor and state render () { return ( <div> <ParentNav /> <CheckoutForm passToken={this.state.token} /> <Footer /> </div> ) } }
Finally Home.js
where the routed are declared
class Home extends React.Component { render() { return ( <div> <HashRouter> <Switch> <Route exact path="/"> <App /> </Route> <Route path="/cart"> <Cart /> <Route path="/cart/checkout" exact component={CheckoutData}/> </Route> <Route path="/product/:id" children={<SingleProduct />} /> </Switch> </HashRouter> </div> ); } }
Advertisement
Answer
Issue
You’ve nested a route within a route
<Route path="/cart"> <Cart /> <Route path="/cart/checkout" exact component={CheckoutData}/> </Route>
The route path “/cart” is a prefix that will match any “/pathXXXXX” path, including “/cart/checkout”. This means when any route’s path includes “/cart” that those routes will be matched and rendered. The Switch
matches and renders the first match.
I tried to set it up as a different route but the component
CheckoutData
won’t render unless I nest into its parentCart.js
.
The reason for this is likely because of the order in which you’ve defined the routes. If you did something like the following:
<Switch> <Route path="/cart"> <Cart /> </Route> <Route path="/cart/checkout" exact component={CheckoutData}/> <Switch>
Then <Route path="/cart">
will always match first and render, no matter what the rest of the path may be.
Solution
Reorder your routes to define more specific paths before less specific paths. The alternative is to append the exact
prop to every Route
, which is both not very DRY, but also tedious and mundane.
<Switch> <Route path="/cart/checkout" // <-- more specific path component={CheckoutData}/> <Route path="/cart"> // <-- less specific path <Cart /> </Route> <Route path="/product/:id" children={<SingleProduct />} /> <Route path="/"> <App /> </Route> </Switch>