反应中的嵌套路由
Nested routing in react
我正在尝试在我的 React 应用程序中实现嵌套路由
我的根 app.jsx 文件中的路由是这样定义的。
<>
<Router>
<DrawerContextProvider>
<Appbar />
<Switch>
<Route exact path='/admin'>
<Admin/>
</Route>
<Route path='/technician' component={Technician} />
<Route path='/accountmanager' component={AccountManager} />
</Switch>
</DrawerContextProvider>
</Router>
</>
这是我管理组件中的代码
function Admin() {
const classes = useStyles();
const { open } = useContext(DrawerContext)
const { url, path } = useRouteMatch();
return (
<>
<SideMenu iconsandnames={iconsandnames} />
<div>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
<Switch>
<Route exact path={path} >
<Dashboard />
</Route>
<Route path={`${path}/:id`} >
<Outlet />
</Route>
</Switch>
</main>
</div>
</>
)
}
function Outlet() {
const { id } = useParams();
console.log(id);
return (
<div>
<h3>{id}</h3>
</div>
);
}
这是我的侧边菜单组件中的代码
export default function MiniDrawer({ iconsandnames }, props) {
const classes = useStyles();
const theme = useTheme();
const { url, path } = useRouteMatch();
const { open, handleDrawerClose } = useContext(DrawerContext)
return (
<div >
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<div className={classes.toolbar}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<Divider />
<List>
{iconsandnames.map((data) => (
data.text == "Home" ? (
<Link to={url}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>):
( <Link to={`${url}/${data.route}`}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>)
))}
</List>
</Drawer>
</div>
);
}
这是我传递到侧边菜单的图标和名称数组
const iconsandnames = [
{
iconname: 'home',
text: 'Home',
route: 'home'
},
{
iconname: 'rounded_corner',
text: 'Projects',
route: 'projects'
},
{
iconname: 'account_box',
text: 'Account managers',
route: 'accountmanagers'
},
{
iconname: 'build',
text: 'Contractors',
route: 'contractors'
},
{
iconname: 'perm_identity',
text: 'Clients',
route: 'clients'
},
{
iconname: 'work_outline',
text: 'Work Orders',
route: 'workorders'
},
{
iconname: 'preview',
text: 'Additional',
route: 'additional'
},
]
http://localhost:3000/admin 告诉我
http://localhost:3000/admin/projects 给我看
理想情况下,当我切换路线时,侧边菜单不应消失,而是在此处消失。关于可能是什么问题以及如何解决它的任何想法?
问题
您在“/admin”路径上指定了 exact
属性,因此无法再匹配和呈现任何嵌套路由。
<Route exact path='/admin'>
<Admin/>
</Route>
管理员
<Switch>
<Route exact path={path} > // <-- can match
<Dashboard />
</Route>
<Route path={`${path}/:id`} > // <-- can't match
<Outlet />
</Route>
</Switch>
解决方案
将 Route
组件渲染成 Switch
时,路径顺序和特异性很重要。您需要将路径从更具体到不太具体排序,以便让更具体的路径有机会在不太具体的路径之前先被匹配和呈现。
路由 - 从“/admin”路由中删除 exact
属性,以便可以匹配任何嵌套路由。
<>
<Router>
<DrawerContextProvider>
<Appbar />
<Switch>
<Route path='/admin'>
<Admin/>
</Route>
<Route path='/technician' component={Technician} />
<Route path='/accountmanager' component={AccountManager} />
</Switch>
</DrawerContextProvider>
</Router>
</>
管理员 - 按特性重新排序路由。
<Switch>
<Route path={`${path}/:id`} >
<Outlet />
</Route>
<Route path={path} >
<Dashboard />
</Route>
</Switch>
我正在尝试在我的 React 应用程序中实现嵌套路由 我的根 app.jsx 文件中的路由是这样定义的。
<>
<Router>
<DrawerContextProvider>
<Appbar />
<Switch>
<Route exact path='/admin'>
<Admin/>
</Route>
<Route path='/technician' component={Technician} />
<Route path='/accountmanager' component={AccountManager} />
</Switch>
</DrawerContextProvider>
</Router>
</>
这是我管理组件中的代码
function Admin() {
const classes = useStyles();
const { open } = useContext(DrawerContext)
const { url, path } = useRouteMatch();
return (
<>
<SideMenu iconsandnames={iconsandnames} />
<div>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
<Switch>
<Route exact path={path} >
<Dashboard />
</Route>
<Route path={`${path}/:id`} >
<Outlet />
</Route>
</Switch>
</main>
</div>
</>
)
}
function Outlet() {
const { id } = useParams();
console.log(id);
return (
<div>
<h3>{id}</h3>
</div>
);
}
这是我的侧边菜单组件中的代码
export default function MiniDrawer({ iconsandnames }, props) {
const classes = useStyles();
const theme = useTheme();
const { url, path } = useRouteMatch();
const { open, handleDrawerClose } = useContext(DrawerContext)
return (
<div >
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<div className={classes.toolbar}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<Divider />
<List>
{iconsandnames.map((data) => (
data.text == "Home" ? (
<Link to={url}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>):
( <Link to={`${url}/${data.route}`}>
<ListItem button key={data.text} >
<ListItemIcon><Icon>{data.iconname}</Icon></ListItemIcon>
<ListItemText primary={data.text} />
</ListItem>
</Link>)
))}
</List>
</Drawer>
</div>
);
}
这是我传递到侧边菜单的图标和名称数组
const iconsandnames = [
{
iconname: 'home',
text: 'Home',
route: 'home'
},
{
iconname: 'rounded_corner',
text: 'Projects',
route: 'projects'
},
{
iconname: 'account_box',
text: 'Account managers',
route: 'accountmanagers'
},
{
iconname: 'build',
text: 'Contractors',
route: 'contractors'
},
{
iconname: 'perm_identity',
text: 'Clients',
route: 'clients'
},
{
iconname: 'work_outline',
text: 'Work Orders',
route: 'workorders'
},
{
iconname: 'preview',
text: 'Additional',
route: 'additional'
},
]
http://localhost:3000/admin 告诉我
http://localhost:3000/admin/projects 给我看
理想情况下,当我切换路线时,侧边菜单不应消失,而是在此处消失。关于可能是什么问题以及如何解决它的任何想法?
问题
您在“/admin”路径上指定了 exact
属性,因此无法再匹配和呈现任何嵌套路由。
<Route exact path='/admin'>
<Admin/>
</Route>
管理员
<Switch>
<Route exact path={path} > // <-- can match
<Dashboard />
</Route>
<Route path={`${path}/:id`} > // <-- can't match
<Outlet />
</Route>
</Switch>
解决方案
将 Route
组件渲染成 Switch
时,路径顺序和特异性很重要。您需要将路径从更具体到不太具体排序,以便让更具体的路径有机会在不太具体的路径之前先被匹配和呈现。
路由 - 从“/admin”路由中删除 exact
属性,以便可以匹配任何嵌套路由。
<>
<Router>
<DrawerContextProvider>
<Appbar />
<Switch>
<Route path='/admin'>
<Admin/>
</Route>
<Route path='/technician' component={Technician} />
<Route path='/accountmanager' component={AccountManager} />
</Switch>
</DrawerContextProvider>
</Router>
</>
管理员 - 按特性重新排序路由。
<Switch>
<Route path={`${path}/:id`} >
<Outlet />
</Route>
<Route path={path} >
<Dashboard />
</Route>
</Switch>