Home > Blockchain >  React Router v6 issues with routes as child component
React Router v6 issues with routes as child component

Time:09-18

I have my app routes in a file like this:

<Route path='/' element={<Home />}>
  <Route index path='/' element={<Feed />} />
  <Route path='friends' element={<Friends />}>
    <Route index element={<>asd</>} />
    <Route path='friend-request' element={<>12</>} />
    <Route path='blocked-friends' element={<>ccc</>} />
    <Route path='add-friends' element={<AddFriends />} />
  </Route>
  <Route path="saved" element={<>Saved</>} /> */}
</Route>

This gets very messy and was thinking of creating separate sub routes components to make it neater like this:

<Route path='/' element={<Home />}>
  <Route index path='/' element={<Feed />} />
  <FriendsRoutes />
  <Route path="saved" element={<>Saved</>} /> */}
</Route>

Where FriendsRoutes is a component with these routes:

<Route path='friends' element={<Friends />}>
  <Route index element={<>asd</>} />
  <Route path='friend-request' element={<>12</>} />
  <Route path='blocked-friends' element={<>ccc</>} />
  <Route path='add-friends' element={<AddFriends />} />
</Route>

But when I do this I get this error:

Uncaught Error: [FriendsRoutes] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

Any Idea how to solve this?

CodePudding user response:

If you are trying to split your code/routes up, that's fine. The error is informing you that only Route and React.Fragment are valid children of the Routes component. The FriendsRoutes component still needs to be rendered on by a Route component.

Exmaple:

<Routes>
  ...
  <Route path='/' element={<Home />}>
    <Route index path='/' element={<Feed />}/>
    <Route path="/friends/*" element={<FriendsRoutes />} /> // *
    <Route path="saved" element={<>Saved</>} />
  </Route>
  ...
</Routes>

* The root path is "/friends/*" with a trailing wildcard "*" matcher so all descendent route paths can also be matched.

FriendsRoutes then needs to render the now descendent routes into another Routes component for route matching to occur.

<Routes>
  <Route element={<Friends />} >
    <Route index element={<>asd</>} />
    <Route path='friend-request' element={<>12</>} />
    <Route path='blocked-friends' element={<>ccc</>} />
    <Route path='add-friends' element={<AddFriends />} />
  </Route>
</Routes>

CodePudding user response:

Edit, the answer by @Drew Reese looks more standard, I'd go with that over what I've outlined here.

The FriendsRoutes component you are creating is not a Route component. It is its own type, and contains a Route component.

I think, off the top of my head, if you wanted this to work, you'd have to do one of the following:

Array of Routes as children

const friendsRoutesArray = () => [
  <Route key="index" index element={<>asd</>} />,
  <Route key="friend-request" path="friend-request" element={<>12</>} />,
  <Route key="blocked-friends" path="blocked-friends" element={<>ccc</>} />,
  <Route key="add-friends" path="add-friends" element={<div />} />
];
<Route path='/'  element={<Home />}>
  <Route index path='/' element={<Feed />}/>
  <Route path='friends' element={<Friends />} >
    {friendsRoutesArray()}
  </Route>
  <Route path="saved" element={<>Saved</>} /> */}
</Route>

Invoke the function, returning the Route

const FriendsRoutes = () => (
  <Route path="friends" element={<div />}>
    <Route index element={<>asd</>} />
    <Route path="friend-request" element={<>12</>} />
    <Route path="blocked-friends" element={<>ccc</>} />
    <Route path="add-friends" element={<div />} />
  </Route>);
<Route path='/'  element={<Home />}>
  <Route index path='/' element={<Feed />}/>
  {FriendsRoutes()}
  <Route path="saved" element={<>Saved</>} /> */}
</Route>
  • Related