React-Admin嵌套路由无法正常工作,组件报错求助
React-Admin嵌套路由正确实现方案
先修复代码中的语法错误
你提供的代码里有个明显的语法错误:create{MenuitemCreate} 应该改为 create={MenuitemCreate},这个错误会导致组件无法被正确识别,也是触发报错的诱因之一。
原写法报错的核心原因
React-Admin 的 <Resource> 组件仅允许 <Resource> 或 <React.Fragment> 作为直接子元素,不能直接嵌套 <Route>,这就是你看到报错的根本原因。要实现嵌套路由,可采用以下两种正确方式:
方式一:在资源的编辑页面内嵌入子路由
如果你的子路由(menuitem-subcategories)依附于具体的 menuitem 详情页面,推荐在 <MenuitemEdit> 组件内部添加嵌套路由:
- 调整
Admin和Resource的基础结构,移除 Resource 内部的 Route:
<Admin dataProvider={dataProvider}> <Resource name="menuitems" options={{ label: 'Item' }} list={MenuitemList} create={MenuitemCreate} edit={MenuitemEdit} /> </Admin>
- 在
MenuitemEdit组件中,结合 React Router 的路由组件,保留原编辑表单的同时嵌入子路由:
import { Edit, SimpleForm, TextInput } from 'react-admin'; import { Routes, Route, Link } from 'react-router-dom'; import MenuitemSubcategoryList from './MenuitemSubcategoryList'; const MenuitemEdit = () => { return ( <div style={{ display: 'flex', gap: '2rem' }}> {/* 左侧展示原编辑表单 */} <div style={{ flex: 1 }}> <Edit> <SimpleForm> <TextInput source="name" /> {/* 其他表单字段 */} </SimpleForm> </Edit> {/* 添加跳转到子路由的入口 */} <Link to="menuitem-subcategories" style={{ marginTop: '1rem', display: 'inline-block' }}> 查看子分类 </Link> </div> {/* 右侧渲染子路由内容 */} <div style={{ flex: 1 }}> <Routes> <Route path="menuitem-subcategories" element={<MenuitemSubcategoryList />} /> </Routes> </div> </div> ); }; export default MenuitemEdit;
- 在
MenuitemSubcategoryList中,通过useParams()获取父资源的 ID,用于过滤对应数据:
import { List, Datagrid, TextField } from 'react-admin'; import { useParams } from 'react-router-dom'; const MenuitemSubcategoryList = () => { const { id } = useParams(); // 获取父 menuitem 的 ID return ( <List resource="menuitem-subcategories" filter={{ menuitemId: id }} // 传递父ID作为数据过滤条件 > <Datagrid> <TextField source="name" /> {/* 其他子分类字段 */} </Datagrid> </List> ); }; export default MenuitemSubcategoryList;
方式二:直接在 <Admin> 下添加独立嵌套路由
如果子路由是独立页面,不需要依附于编辑页面,可直接在 <Admin> 组件下添加 <Route>,路径包含父资源的 ID:
import { Admin, Resource } from 'react-admin'; import { Route } from 'react-router-dom'; import MenuitemList from './MenuitemList'; import MenuitemCreate from './MenuitemCreate'; import MenuitemEdit from './MenuitemEdit'; import MenuitemSubcategoryList from './MenuitemSubcategoryList'; const App = () => { return ( <Admin dataProvider={dataProvider}> <Resource name="menuitems" options={{ label: 'Item' }} list={MenuitemList} create={MenuitemCreate} edit={MenuitemEdit} /> {/* 添加独立的嵌套路由 */} <Route path="/menuitems/:id/menuitem-subcategories" element={<MenuitemSubcategoryList />} /> </Admin> ); }; export default App;
这种方式下,MenuitemSubcategoryList 同样可以通过 useParams() 获取父资源的 ID,实现对应数据的加载或过滤。
内容的提问来源于stack exchange,提问作者Mario Redonavich
相关产品推荐
相关产品推荐

