German Cocca
German Cocca

Reputation: 849

Problem with react router link and nested routing

I have an application with react router implemented, and within one of the components I nested another router since I need to be able to navigate to different subcomponents from that component.

The implementation worked fine until I tried to build a link to be able to get out of that specific component and navigate the 'mother' router.

For some reason I can't understand, when I click on the link the URL changes correctly but the components displayed don't change. The component I'm trying to get out of stays there and the component I'm trying to get to doesn't render.

Any tips or ideas are more than welcome. Full code can be found here: https://github.com/coccagerman/sweetkicks

This is the main router:

        <Router>

      <Context.Provider value={{ wishList: wishList, wishlistAdd: wishlistAdd, wishlistSubstract: wishlistSubstract, shoppingCart: shoppingCart, shoppingCartAdd: shoppingCartAdd, shoppingCartSubstract: shoppingCartSubstract, emptyShoppingCart: emptyShoppingCart, addNumberThousandSeparator: addNumberThousandSeparator, findInWishlist: findInWishlist, searchParams: searchParams, setSearchParams: setSearchParams }}>

        <Header setDarkMode={setDarkMode} darkMode={darkMode} productsDataBase={productsDataBase} setProductsArray={setProductsArray} />

        <Switch>
          <Route path='/' exact>
            <Hero darkMode={darkMode} productsDataBase={productsDataBase} setProductsArray={setProductsArray} />
          </Route>

          <Route path='/gallery'>
            <Gallery darkMode={darkMode} productsDataBase={productsDataBase} productsArray={productsArray} setProductsArray={setProductsArray} />
          </Route>

          <Route path='/item'>
            <Item  />
          </Route>

          <Route path='/shoppingcart'>
            <ShoppingCart />
          </Route>

          <Route path='/wishlist'>
            <Wishlist />
          </Route>

          <Route path='/checkout'>
            <Checkout />
          </Route>

          <Route path='/orders'>
            <MyOrders />
          </Route>

          <Route path='/about'>
            <About productsDataBase={productsDataBase} setProductsArray={setProductsArray} />
          </Route>
        </Switch>

        <Footer />

      </Context.Provider>

    </Router>

This is the nested router, inside the CheckoutForm component, which is a child of Checkout component:

        <Router>
        <Switch>
            <Route path='/checkout/personalDataFormStep'>
                <PersonalDataFormStep setFullName={setFullName} setTelephone={setTelephone} setEmail={setEmail} />
            </Route>

            <Route path='/checkout/addressFormStep'>
                <AddressFormStep setAddress={setAddress} setCity={setCity} setLocation={setLocation} />
            </Route>

            <Route path='/checkout/creditCardFormStep'>
                <CreditCardFormStep setCardNumber={setCardNumber} setInstallments={setInstallments} />
            </Route>

            <Route path='/checkout/confirmationFormStep'>
                <ConfirmationFormStep purchaseData={purchaseData} />
            </Route>

            <Route path='/checkout/completionFormStep'>
                <CompletionFormStep />
            </Route>
        </Switch>   
    </Router>

These are the links I'm trying to implement, within the CompletionFormStep component, which is a child of CheckoutForm component:

                <Link to="orders" >
                <button className='btn-secondary'>My orders</button>
            </Link>
            <Link to="/gallery" >
                <button className='btn-primary'>Explore</button>
            </Link>

Upvotes: 1

Views: 597

Answers (1)

Ajeet Shah
Ajeet Shah

Reputation: 19863

You need <Router/> only once at root level. You should remove <Router> from the nested CheckoutForm component.

Also, it is better to create nested routes using path and url from the react router context, an example:

const CheckoutForm = () => {
  const { path } = useRouteMatch();
  return (
    <Switch>
      <Route path={`${path}/confirmationFormStep`}> // using path here
        <ConfirmationFormStep purchaseData={purchaseData} />
      </Route>
      <Route path={`${path}/completionFormStep`}> // and here
        <CompletionFormStep />
      </Route>
    </Switch>
  );
};

Upvotes: 1

Related Questions