React Router Pathing – How to Navigate Paths in React Router

react-routerreactjs

I would like to understand better how the useNavigate works as I'm not really understanding the pattern.

This is my Routes

<BrowserRouter>
      <Routes>
        <Route path="/" element={<Homepage />} />
      </Routes>
      <Routes>
        <Route path="/questionaire" element={<Questionaire />} />
        <Route path="questionaire/1" element={<Question1 />} />
        <Route path="questionaire/2" element={<Question1 />} />
      </Routes>
    </BrowserRouter>

On the Questionaire page I use navigate("1") and it goes into the path "/questionaire/1"
Nice!

Now on question1 I want to go into "/questionaire/2":

  • navigate("2") – leads me into /questionaire/1/2
  • navigate("/2") – leads me into /2
  • navigate("questionare/2") – leads me into /questionaire/1/questionaire/2

How do I make an increment so every question just adds ++
How do I go from questionaire/5 into questionaire/2 using navigate?

I'm using navigate in buttons, should I use LINK? with a button nested in it? Why?

EDIT: doesn't necessarily have to increment the value, but just replace the current number with the one I want – ex question/1 to question/2 or from question/5 to question/3

Best Answer

What you are asking about is the fundamental difference between absolute and relative routing. In react-router-dom@6 the only thing that differentiates relative links and routes from absolute links and routes is the leading "/" character.

  • Absolute links and routes:

    • Begin with a leading "/" character, i.e. "/root/segment1/segment2"

    • Replace the entire path

      // "/root/segment1"
      navigate("/root/otherPath");
      // "/root/otherPage"
      
  • Relative links and routes:

    • Do not begin with a leading "/" character, i.e. "segment2"

    • Append to the current path

      // "/root/segment1"
      navigate("otherPath");
      // "/root/segment1/otherPage"
      

      ...

      // "/root/segment1"
      navigate("../otherPath");
      // "/root/otherPage"
      

I suggest the following route refactor:

  • All sibling routes can be wrapped and rendered by a single Routes component.
  • Use layout and index routes to help manage/organize nested routes.

Code

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Homepage />} />
    <Route path="/questionaire">
      <Route index element={<Questionaire />} /> // "/questionaire"
      <Route path="1" element={<Question1 />} /> // "/questionaire/1"
      <Route path="2" element={<Question2 />} /> // "/questionaire/2"
      ...
      <Route path="<N>" element={<QuestionN />} /> // "/questionaire/<N>"
    </Route>
  </Routes>
</BrowserRouter>

Use absolute paths to navigate from to the parent path or from question to question:

navigate("/questionaire");   // to parent
navigate("/questionaire/1"); // to question #
navigate("/questionaire/2");
navigate("/questionaire/N");

Use relative paths from the parent layout route on path="/questionaire":

navigate("..");   // to parent
navigate("../1"); // to question #
navigate("../2");
navigate("../N");

Notice here that we can use ".." to navigate relatively to the parent route. This is useful to navigate along sibling components.

Related Question