浅析React Router V6 useRoutes的使用
本篇文章记录了useRoutes第一个参数的使用方法,暂不涉及第二个参数。
·
本篇文章记录了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
的第一个参数进行学习,之后有空的话会抽空继续学习第二个参数的用法。
更多推荐
已为社区贡献2条内容
所有评论(0)