Skip to content
Advertisement

I can’t display nested route in different view

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 parent Cart.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>
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement