Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: #8252

Closed
richtera opened this issue Nov 6, 2021 · 11 comments
Closed

[Bug]: #8252

richtera opened this issue Nov 6, 2021 · 11 comments
Labels

Comments

@richtera
Copy link

richtera commented Nov 6, 2021

What version of React Router are you using?

Just upgraded from 6.0.0 to 6.0.1

Steps to Reproduce

<Route path="/" element={...</Outlet>...}>
  <Routes>
     <Route....
  </Routes>
</Route>

Now throws an error
Uncaught Error: [Routes] is not a component. All component children of must be a or <React.Fragment>

Expected Behavior

This should work just as it did in 6.0.0 unless this is supposed to work completely different now.
I didn't see anything in release notes.

Actual Behavior

Just crashes.
6.0.0 works fine.

@richtera
Copy link
Author

richtera commented Nov 6, 2021

I tried

<Route path="/" element={...</Outlet>...}>
  <Route....
  <Route....
</Route>

but could not get it to work without the Routes in between.

@Joker-Bat
Copy link

I tried

<Route path="/" element={...</Outlet>...}>
  <Route....
  <Route....
</Route>

but could not get it to work without the Routes in between.

I think your parant Route need to be wrapped inside Routes, not for the nested Route,

e.x:

<Routes>
  <Route path="/" element={...</Outlet>...}>
    <Route....
    <Route....
  </Route>
</Routes>

@richtera
Copy link
Author

richtera commented Nov 7, 2021

I have both wrapped. I have a few full screen routes, then another route with a routes in it and an outlet.

@richtera
Copy link
Author

richtera commented Nov 7, 2021

Here is my use case...

function Main() {
  return isLoggedIn ? (
    <Routes>
      <Route path="/view/:itemId/:subItemId/:subSubITemId?/actions" element={... full screen actions page ....} />
      <Route
        path="/course/:course/wizard/:lesson/:activity?/actions"
        element={... full screen actions page ...}
      />
      <Route path="/item/:itemId/actions" element={... full screen actions page ...} />
      <Route
        path="/"
        element={
          <div className="vh-min-100 d-flex flex-column w-100">
            <header>
              ... header stuff ...
            </header>
            <main className="mb-auto">
              <SideNav/>
              <Outlet />
            </main>
            <Footer />
          </div>
        }
      >
        <Routes>
          <Route
            path="/items"
            element={... embedded list page ...}
          />
          <Route
            path="/"
            element={
              ... embeded home page ....
            }
          />
          <Route
            path="/item/:itemId/progress"
            element={... embedded item progress page ...}
          />
          <Route path="/item/:itemId/test" element={... embedded item details page ...}>
          <Route path="/item/:itemId" element={... embedded item page ...} />
          <Route
            path="/profile-settings"
            element={... embedded profile settings }
          />
          <Route path="/profile" element={... embedded profile page ...} />
        </Routes>
      </Route>
    </Routes>
  ) : (
    <Routes>
      <Route
        path="/"
        element={... welcome page ...}
      />
      <Route
        path="/*"
        element={ ... welcome page with error ...}
      />
    </Routes>
  );
}

This setup works correctly in 6.0.0, and will crash under 6.0.1. Removing the inner Routes element doesn't seem to work. It looks like Outlet always needs a Routes wrapper to source from which makes sense.

@timdorr
Copy link
Member

timdorr commented Nov 7, 2021

You don't make Routes the children of a Route, just as you wouldn't make any non-Route element the children of a Route. You use the element prop instead.

The warning is telling you you're doing the wrong thing, so it's working correctly.

@timdorr timdorr closed this as completed Nov 7, 2021
@richtera
Copy link
Author

richtera commented Nov 7, 2021

I'll do some research and see.... no need to tie this up as a github issue.

@richtera
Copy link
Author

richtera commented Nov 8, 2021

It does work with skipping the inner although I feel it's a bit confusing. The outer one needs Routers in order to support an Outlet and the inner Route/Route section automatically populates an Output on the parent Route. Not quite sure why Routes is really needed on the outer one then, but ok. It is how it is. It didn't immediately work for me, because Routes vs Switch is a lot less forgiving due to not allowing splats and exact being assumed.

@Joker-Bat
Copy link

It does work with skipping the inner although I feel it's a bit confusing. The outer one needs Routers in order to support an Outlet and the inner Route/Route section automatically populates an Output on the parent Route. Not quite sure why Routes is really needed on the outer one then, but ok. It is how it is. It didn't immediately work for me, because Routes vs Switch is a lot less forgiving due to not allowing splats and exact being assumed.

In a single component you need to use only one pair of Routes, if you are managing some route in seperate component then those also should be wrapped by Routes.

Route always should be inside Routes.

@andreawyss
Copy link

@richtera I have similar problem with nested routes where route groups are lazy loaded from a Webpack Federated Module.
Can you show how you solved the nested routes issue that you had?
Maybe this can help others.

@richtera
Copy link
Author

Basically Routes can only be rendered in the Ui tree. So either at the root or inside of an element. Within Routes you can only have Route which in turn can contain other Route. When there is a nested rout me it will mount the corresponding element in the Outlet of the parent Route element. It's a bit confusing because I thought Routes is what provided the Outlet functionality but it in fact is Route itself. Did I get this right I hope? But that's how I got it to work

@andreawyss
Copy link

andreawyss commented Nov 13, 2021

I ended up using useRoutes to combine arrays of routeObjects from several micro frontends.

The code now with useRoutes is so much simpler. Thank you for amazing v6 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants