本篇文章记录了useRoutes第一个参数的使用方法,暂不涉及第二个参数。
一、使用位置
一开始以为可以像react-router-config那样使用,于是写成
import { BrowserRouter as Router, useRoutes } from 'react-router-dom';
const SetRoutes = () => {
const routes = useRoutes([
{
path:'/',
element: <div>...</div>
},
{
path:'/a',
element: <div>aaa</div>
}
]);
return (
<Router>
{routes}
</Router>
)
}
结果报错useRoutes() may be used only in the context of a <Router> component.
啥?这不是已经包裹在<Router>中了吗。
看过其他例子后才知道,需要将使用了useRoutes的整个组件都放入<Router>当中,就像下面这样
import { BrowserRouter as Router, useRoutes } from 'react-router-dom';
const GetRoutes = () => {
const routes = useRoutes([
{
path:'/',
element: <div>...</div>
},
{
path:'/a',
element: <div>aaa</div>
}
]);
return routes;
}
const SetRoutes = () => {
return (
<Router>
<GetRoutes />
</Router>
)
}
二、嵌套路由
嵌套路由就是在有子路由的路由中设置children,例如:
import {
BrowserRouter as Router,
Outlet,
useRoutes
} from 'react-router-dom';
const GetRoutes = () => {
const routes = useRoutes([
{
path:'/',
element: <div>...</div>
},
{
path:'/a',
element: <><div>aaa</div><Outlet></>,
children: [
{
path: 'b', // 这里的path,写为'/b',也可以 /加不加都行
element: <div>bbb</div>
}
]
}
]);
return routes;
}
const SetRoutes = () => {
return (
<Router>
<GetRoutes />
</Router>
)
}
上面的代码相当于
import {
BrowserRouter as Router,
Outlet,
Routes,
Route
} from 'react-router-dom';
const SetRoutes = () => {
return (
<Router>
<Routes>
<Route path='/' element={<div>...</div>} />
<Route path='/a' element={<><div>aaa</div><Outlet /></>} >
<Route path='b' element={<div>a-bbb</div>} />
// 或者写为<Route path='/a/b' element={<div>a-bbb</div>} />
</Route>
</Routes>
</Router>
)
}
三、分模块管理
如果项目比较大,可能很多页面共用一段相同的路径,但是又不是嵌套路由的关系,每次往useRoutes添加路由都要写完整的path感觉麻烦怎么办?
就比如一个项目通常分为前台页面和后台页面,我们可以将前台页面和后台页面分开来管理,例如:
import {
BrowserRouter as Router,
useRoutes
} from 'react-router-dom';
import RecLayout from 'xxxx';
import AdminLayout from 'xxxx';
const GetRecRoutes = () => { // 获取前台路由
const routes = useRoutes([
{
path:'',
element: <RecLayout />,
children: [
{
path: '',
element: <div>前台首页</div>
},
{
path: 'a',
element: <div>rec-aaa</div>
}
]
},
{
path: '*',
element: <div>前台404</div>,
}
]);
return routes;
}
const GetAdminRoutes = () => { // 获取后台路由
const routes = useRoutes([
{
path:'',
element: <AdminLayout />,
children: [
{
path: '',
element: <div>后台首页</div>
},
{
path: 'a',
element: <div>admin-aaa</div>
},
]
},
{
path: '*',
element: <div>后台404</div>,
}
]);
return routes;
}
const GetAllRoutes = () => {
const routes = useRoutes([
{
path: '/*',
element: <GetRecRoutes />,
},
{
path:'/admin/*',// 末尾的 /* 必不可少
element: <GetAdminRoutes />,
},
{
path: '*', // 这个404页面不会被匹配到
element: <div>404</div>,
}
])
return routes;
}
const SetRoutes = () => {
return (
<Router>
<GetAllRoutes />
</Router>
)
}
注意事项
1、因为前台页面的path我写为了'/*',所以404页面得在前后台的useRoutes中分别添加,否则遇到没有页面的路径,也会匹配到前台的路由当中,从而显示空白页面
2、拿后台路由举例,path中'/admin/*'末尾的'/*'必不可少,否则后台路由只会精确匹配到/admin路径,访问/admin/a将不会匹配到后台路由而是进入前台路由当中,而前台路由又没有相对应的页面,将会展示404页面
3、这里即使我将'/admin/*'放在'/*'后面,在访问/admin时,依然会匹配到后台的页面
目前暂时只对useRoutes的第一个参数进行学习,之后有空的话会抽空继续学习第二个参数的用法。
版权声明:本文为ncgNCGg原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。