skip to Main Content

I have another piece of code and want to know the principle of react-router url matching. For example, the following code does not render the Layout component under "/login", which is the effect I want, but I want to know why. Can someone explain?

<Router>
  <Suspense fallback={<PageLoading />}>
    <Routes>
      <Route
        path='/*'
        // Layout render another routes but no /login path
        element={<Layout /> }
      />
      <Route 
        path='/login'
        element={<LoginPage />}
      />
    </Routes>
  </Suspense>
</Router>

Layout code

const Layout = () => {
  return (
    <div>
      <div>main page xxxx</div>
      <div>
        <Routes>
          <Route
            path='/demo1'
            element={<Demo1 /> }
          />
          <Route
            path='/demo2'
            element={<Demo2 /> }
          />
        </Routes>
      </div>
    </div>
  )
}

When path is "/login", will the Layout component render something? How does the react-router@6 match url?

2

Answers


  1. The basic gist is that react-router works by conditionally rendering selected UI based on matching the current URL path to a set of configured routes.

    Route matching in react-router@6 uses a Path Ranking System to compute a score, or rank, for all route paths within a given Routes component . The Routes component takes the current URL path and matches it to the highest ranked route, by path, that it is managing. Generally speaking, the more specific the route path is, the higher the rank. The ranking mostly serves to break ties between competing matches since ultimately only 1 can be matched and rendered.

    Think of the Routes component as a switch statement where the condition is the path match to the current URL path. In fact, the Routes component replaced the older v5 Switch component.

    For the routes configuration:

    <Routes>
      <Route path="/*" element={<Layout /> } />
      <Route path="/login" element={<LoginPage />} />
    </Routes>
    

    When the URL is "domain/login", the best match is obviously the "/login" route. This route will be matched and the LoginPage will be rendered. The Layout component is not rendered at all, nor is it even mounted in the ReactTree.

    On the other hand, when the URL is anything but "domain/login", something like "domain/foo", then "/login" cannot be matched and the next highest ranked route, "/*" is the best match and the Layout component is rendered. LoginPage is now not rendered or mounted at all.

    Login or Signup to reply.
  2. in react-router, you can not use it like that. In the first block you already declare and that’s why you can not push another in the layout. The solution will be like that you can try this:

    <Router>
      <Suspense fallback={<PageLoading />}>
        <Routes>
          <Route
            path='/'
           // Layout renders another routes but no /login path
            element={<Layout /> }
          />
          <Route 
            path='/login'
            element={<LoginPage />}
          />
          <Route
            path='/demo1'
            element={<Demo1 /> }
          />
          <Route
            path='/demo2'
            element={<Demo2 /> }
          />
        </Routes>
      </Suspense>
    </Router>
    

    In layout, you can try like this

    const Layout = () => {
      return (
        <div>
          <div>main page xxxx</div>
          <div>
              <Link
                to='/demo1'
              />
              <Link
                to='/demo2'
              />
          </div>
        </div>
      )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search