javascript - ¿Cómo puedo crear un subrouter con React Router v6?
Aquí está mi implementación actual de React Router:
const router = createBrowserRouter([
{
path: "/",
element: (
<Page activeNav="home" >
<Home />
</Page>
)
},
{
path: "/about",
element: (
<Page activeNav="about" >
<About />
</Page>
)
},
{
path: "/blog",
element: (
<Page activeNav="blog">
<Blog />
</Page>
)
},
{
path: "/blog/:postName",
element: (
<Page activeNav="blog" >
<Post />
</Page>
),
loader: ({ params }) => params.postName
},
{
path: "/chess",
element: <ChessRouter />
}
])
La última ruta, /chess, es importante. Estoy buscando definir rutas como /chess/play, /chess/login, /chess/register, etc. Mi idea inicial era simplemente poner otro Router como el elemento para la ruta /chess y entonces todas esas rutas se encaminarían desde allí. Sin embargo, eso lanza un error que dice:
You cannot render a <Router> inside another <Router>. You should never have more than one in your app.
También intenté usar la propiedad children en la ruta /chess, pero esto no muestra nada cuando voy a /chess/play, etc.
¿Cuál es la manera correcta de implementar subrutas (no estoy seguro de la palabra correcta para ello)?
Respuesta #1
Es correcto que no puedes renderizar un componente de router dentro de otro componente de router, ya que esto es una violación de invariante. Solo necesitas un router y un contexto de enrutamiento por aplicación de React.
Para renderizar subrutas en "/chess" entonces hay dos opciones:
Renderiza rutas anidadas en la declaración de configuración de rutas. Esto requiere que el componente
ChessRouterrenderice un componenteOutletpara que las rutas anidadas puedan renderizar su contenido deelement. Las rutas anidadas podrán usar las nuevas APIs de Datos de RRDv6.4.const router = createBrowserRouter([ ..., { path: "/chess", element: <ChessRouter />, children: [ ..., { path: "play", element: <ChessPlay /> }, ... other chess sub-routes ], } ]);const ChessRouter = () => { ... return ( ... <Outlet /> ... ); };Renderiza una ruta raíz con un carácter comodín final (
"*") que permite que las rutas descendientes también sean coincidentes. Esto permite que el componenteChessRouterrenderice rutas descendientes, es decir, un componenteRoutescon un conjunto de componentesRoute. Las rutas descendientes no podrán usar las API de datos de RRDv6.4.const router = createBrowserRouter([ ..., { path: "/chess/*", element: <ChessRouter />, } ]);const ChessRouter = () => { ... return ( ... <Routes> ... <Route path="/play" element={<ChessPlay />} /> ... other chess sub-routes </Routes> ... ); };
Respuesta #2
Si tu ChessRouter no contiene ninguna funcionalidad adicional además de las declaraciones de rutas, podrías eliminarlo por completo y usar una ruta de índice.
Trabajando a partir de lo que Drew tenía:
const router = createBrowserRouter([
...,
{
path: "/chess",
children: [{
index: true,
element: <ChessPlay /> // The default component to load at '/chess'
},
{
path: "play",
element: <ChessPlay />
},
... other chess sub-routes
],
}
]);
Esto permitirá que todas tus rutas secundarias bajo /chess funcionen, así como evitar que se muestre una página en blanco si un usuario accede a la ruta base /chess.
