React中<Routes>无法渲染含<Route>的容器组件的解决方案咨询
解决React路由拆分的警告问题
警告原因
Routes组件的直接子元素只能是<Route>或<React.Fragment>,你现在直接把自定义的<Categories>、<Details>组件放进<Routes>里,不符合规则,所以触发警告。
解决方案
下面提供三种可行的拆分方式,按需选择:
方式一:导出Route元素数组(最简单直接)
修改Categories.js,不要返回组件,直接导出路由元素数组:
// Categories.js import { Route, Navigate } from 'react-router-dom'; import Movies from './Movies'; import Tv from './Tv'; import People from './People'; import Search from './Search'; export const categoryRoutes = [ <Route key="root" path="/" element={<Navigate replace to="/movie" />} />, <Route key="movie" path="/movie" element={<Movies />} />, <Route key="tv" path="/tv" element={<Tv />} />, <Route key="person" path="/person" element={<People />} />, <Route key="search" path="/search" element={<Search />} /> ];
修改Details.js同理:
// Details.js import { Route } from 'react-router-dom'; import MovieDetail from './MovieDetail'; import TvDetail from './TvDetail'; import PersonDetail from './PersonDetail'; export const detailRoutes = [ <Route key="movieDetail" path="/movie/:tmdbID" element={<MovieDetail />} />, <Route key="tvDetail" path="/tv/:tmdbID" element={<TvDetail />} />, <Route key="personDetail" path="/person/:tmdbID" element={<PersonDetail />} /> ];
然后在App.js中导入并展开这些数组:
// App.js import { BrowserRouter, Routes } from 'react-router-dom'; import Header from './Header'; import Nav from './Nav'; import { categoryRoutes } from './Categories'; import { detailRoutes } from './Details'; const App = () => { return ( <div className="app__container"> <Header /> <Nav /> <BrowserRouter> <Routes> {categoryRoutes} {detailRoutes} </Routes> </BrowserRouter> </div> ) } export default App;
方式二:使用路由配置对象 + useRoutes钩子(更简洁)
这种方式用纯对象定义路由,适合路由较多的场景。
修改Categories.js导出路由配置对象:
// Categories.js import { Navigate } from 'react-router-dom'; import Movies from './Movies'; import Tv from './Tv'; import People from './People'; import Search from './Search'; export const categoryRouteConfig = [ { path: "/", element: <Navigate replace to="/movie" /> }, { path: "/movie", element: <Movies /> }, { path: "/tv", element: <Tv /> }, { path: "/person", element: <People /> }, { path: "/search", element: <Search /> } ];
修改Details.js同理:
// Details.js import MovieDetail from './MovieDetail'; import TvDetail from './TvDetail'; import PersonDetail from './PersonDetail'; export const detailRouteConfig = [ { path: "/movie/:tmdbID", element: <MovieDetail /> }, { path: "/tv/:tmdbID", element: <TvDetail /> }, { path: "/person/:tmdbID", element: <PersonDetail /> } ];
在App.js中合并配置并使用useRoutes渲染:
// App.js import { BrowserRouter, useRoutes } from 'react-router-dom'; import Header from './Header'; import Nav from './Nav'; import { categoryRouteConfig } from './Categories'; import { detailRouteConfig } from './Details'; const App = () => { // 合并两类路由配置 const renderedRoutes = useRoutes([...categoryRouteConfig, ...detailRouteConfig]); return ( <div className="app__container"> <Header /> <Nav /> <BrowserRouter> {renderedRoutes} </BrowserRouter> </div> ) } export default App;
方式三:嵌套路由(适合有共享布局的场景)
如果你的分类页或详情页有共享的UI布局(比如侧边栏、面包屑),可以用嵌套路由配合Outlet:
修改Categories.js为布局组件:
// Categories.js import { Route, Navigate, Outlet } from 'react-router-dom'; import Movies from './Movies'; import Tv from './Tv'; import People from './People'; import Search from './Search'; // 共享布局组件(如果不需要布局,直接返回<Outlet />即可) const CategoryLayout = () => { // 这里可以加共享UI,比如分类导航栏 return <Outlet />; }; export const categoryRoutes = ( <Route element={<CategoryLayout />}> <Route path="/" element={<Navigate replace to="/movie" />} /> <Route path="/movie" element={<Movies />} /> <Route path="/tv" element={<Tv />} /> <Route path="/person" element={<People />} /> <Route path="/search" element={<Search />} /> </Route> );
修改Details.js同理:
// Details.js import { Route, Outlet } from 'react-router-dom'; import MovieDetail from './MovieDetail'; import TvDetail from './TvDetail'; import PersonDetail from './PersonDetail'; const DetailLayout = () => { // 这里可以加详情页的共享UI return <Outlet />; }; export const detailRoutes = ( <Route element={<DetailLayout />}> <Route path="/movie/:tmdbID" element={<MovieDetail />} /> <Route path="/tv/:tmdbID" element={<TvDetail />} /> <Route path="/person/:tmdbID" element={<PersonDetail />} /> </Route> );
在App.js中导入使用:
// App.js import { BrowserRouter, Routes } from 'react-router-dom'; import Header from './Header'; import Nav from './Nav'; import { categoryRoutes } from './Categories'; import { detailRoutes } from './Details'; const App = () => { return ( <div className="app__container"> <Header /> <Nav /> <BrowserRouter> <Routes> {categoryRoutes} {detailRoutes} </Routes> </BrowserRouter> </div> ) } export default App;
内容的提问来源于stack exchange,提问作者Kevin Mahendra
相关产品推荐
相关产品推荐

