我曾经做过一个有类似要求的项目。在这种情况下,我没有声明动态路由,而是从状态中获取了一个路由数组,该数组是一个包含组件、路径和一些其他参数的对象数组。默认情况下,我添加了初始登陆页面和未找到页面:
const [routes, setRoutes] = React.useState([
{
component: HomeComponent,
path: '/',
},
{
component: NoMatchPage,
path: '*',
}
])
然后我在 useEffect 块中收到请求,该请求将更新此状态,如下所示:
React.useEffect(()=>{
// call api()
const oldRoutes = routes;
const noMatchPage = oldRoutes.pop();
const newRoutes = [...oldRoutes,
responseFromApi.map(
routeItem =>
({
component: ComponentName,
path: routeItem.path
})
), noMatchPage]
setRoutes(newRoutes)
},[])
编辑1:因为我很健忘
抱歉,我忘记了主要部分,以下是路线渲染的样子:
<Switch>
{
routes.map(routeItem =>
<Route path={routeItem.path} component={routeItem.component} />
)
}
</Switch>
另外,如果你想避免 useEffect 中的额外代码,你可以简单地这样做:
React.useEffect(()=>{
// call api()
setRoutes(responseFromApi.map(
routeItem =>
({
component: ComponentName,
path: routeItem.path
})
))
},[])
and then
<Switch>
<Route exact path={["/home", "/"]} component={Home} />
{
routes.map(routeItem =>
<Route path={routeItem.path} component={routeItem.component} />
)
}
<Route component={NotFound} />
</Switch>
编辑2:因为我无知
如果用户直接输入 URL 并Switch
无法识别Route
因此加载NotFoundPage
,您可以执行以下操作:
- 当您开始加载路径时设置一个条件,在您的
useEffect
block:
const [loading, setLoading] = React.useState(false);
React.useEffect(() =>
{
setLoading(true);
// load paths
setLoading(false);
}, [])
- 当获取正在进行时,显示
Loader
致用户:
return
(
<>
{
loading ?
<LoaderComponent /> :
<Switch>
// same as before
</Switch>
}
</>
)
最好展示一些内容供用户阅读,这样他们就不会被激怒,因为耐心已经成为过去。希望这可以帮助!