Home > OS >  React router v6 nested routes can't go up one level using navigate
React router v6 nested routes can't go up one level using navigate

Time:06-28

Target

I'm using react router v6.

I have a parent route with a static header with a back button that when I click it needs to go one path above, exp. /shop/1/item/create to /shop/1/item, when i click the back button i call the function navigate from useNavigate()

example

example

Red is the root page, yellow is where the static header is and green is content that i want to change

Problem

When i call navigate regardless of using "." or ".." or "./" the page never change correctly, it either redirects from /shop/1/items/create to /shop or to /shop/1

the only way of redirecting correctly is using -1 but it causes the problem that if someone copy's the URL when going back they get redirected to whatever page they were before pasting the URL.

Code

    const ShopPage = () => {
    
        const [ state, setState ] = React.useState<IShopPageState>({ shop: { name: "" }, isInvalid: false })
        const { id } = useParams()
        const navigate = useNavigate()
        
        return (
            <div id="shop-page">
                <Card>
                    <div id="shop-page-header">
                        <Icon canHover onClick={() => navigate("./")} icon="BiArrowBack"/>
                        <Title text={state.shop ? state.shop.name : ""}/>
                    </div>
                </Card>
                <div id="shop-page-content">
                    <Routes>
                        <Route path="/*" element={<div onClick={() => navigate('./items')}>wddw</div>}/>
                        <Route path="/items/*" element={<ItemsPage shop={state.shop}/>}/>
                        <Route path="/items/create" element={<ItemPage/>}/>
                    </Routes>
                </div>
            </div>
        )
    }

Here is the code of the yellow part with only the important stuff, the header is static and always visible and where the back button is. I believe this code is enough to understand, the green part only redirects the url from /items/ to /items/create using navigate('./create')

I think a possible solution would be simply copying pasting the header for each page but i find that to be bad practice and it is a last resort solution

Here is a example of the problem

EDIT

As asked here is some extra code showing the problem

App.js

export default function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="*" element={<Link to="/shop">Shop</Link>} />
        <Route path="shop/*" element={<Shop />} />
      </Routes>
    </BrowserRouter>
  );
}

Shop.js

const Shop = () => {
  return (
    <>
      <div>
        <Link to="./">Back</Link>
      </div>
      <Routes>
        <Route path="*" element={<Link to="./items">All</Link>} />
        <Route path="items/*" element={<Link to="./create">Item</Link>} />
        <Route path="items/create" element={<>Create</>} />
      </Routes>
    </>
  );
};

CodePudding user response:

if you are using a nested route then better to use

<Route path="/" >
  <Route index element={<Items/>} />
  <Route path="item:id" element={<Item/>} />
</Route> 

CodePudding user response:

Hey Dear @pekira you can see just a simple hint in the code below for React Router v6

 import { Routes, Route, Link } from 'react-router-dom';

  const App = () => {
    return (
      <>
        <h1>React Router</h1>

        <nav>
          <Link to="/home">Home</Link>
          <Link to="/user">User</Link>
        </nav>

        <Routes>
          <Route index element={<Home />} />
          <Route path="home" element={<Home />} />
          <Route path="user/:Id" element={<User />} />
          <Route path="*" element={<NoMatch />} />
        </Routes>
      </>
    );
  };
  • Related