React Router 6动态深层嵌套路由实现问题求助
动态嵌套路由问题求助
项目背景
我正在开发一个电商练手项目,分为展示区和管理面板:
- 管理面板路由均以
domain.com/admin/开头,支持商品、分类、品牌的增删改 - 其余路由对应展示区,布局为:头部分类菜单 → 分类商品列表 → 商品详情
当前路由配置
const routes = useRoutes([ { path: PATHS.showcase, element: <ShowcasePage />, children: [ { path: '/', element: <DiscountProductsPage />, }, { path: ':url', children: [ { index: true, element: <CategoryPage />, }, { path: ':id', element: <ProductsPage />, }, ], }, { path: PATHS.wishlist, element: <WishlistPage /> }, ], }, { path: PATHS.admin, element: <AdminPage />, children: [ { path: PATHS.products, element: <ProductsPage /> }, { path: PATHS.settings, element: <SettingsPage />, }, ], }, ]);
路径定义:
export const PATHS = { showcase: '/', settings: 'settings', products: 'products', admin: '/admin/', wishlist: '/wishlist' }
分类数据与菜单实现
页面加载后获取分类数组:
const categories = [ { id: '-N8A28QULvmu36EqRZDW', description: '', name: 'Hoodies', url: 'hoodies', }, { id: '-z34A29MMMvmu36EqRZXX', description: '', name: 'Jeans', url: 'jeans', }, ];
基于分类数组生成头部菜单,通过Link的state传递分类信息:
<nav> <ul> {categories.map((category) => ( <li key={category.id}> <Link to={category.url} state={category} onClick={closeMenu}> {category.name} </Link> </li> ))} </ul> </nav>
分类页面实现
通过location.state获取分类数据并渲染商品列表:
const CategoryPage: React.FC = () => { const location = useLocation(); const { id, name } = location.state as Category; const { products } = useSelector((state: RootState) => state.product); const categoryProducts = products.filter((product) => product.category.id === id); return ( <section> <h1>{name}</h1> <ProductCardList products={categoryProducts} /> </section> ); };
问题与需求
我想实现:点击分类页商品卡片时,跳转至domain.com/:categoryUrl/:productId格式的商品页,于是给CategoryPage路由添加了:id子路由,但此时CategoryPage报错:
Uncaught TypeError: Cannot destructure property 'id' of 'location.state' as it is null.
我的核心需求:
- 点击头部分类菜单,进入对应分类商品列表页
- 点击分类页商品,进入
domain.com/jeans/-s1B99QULvmu36EqCCPP格式的商品详情页 - 商品页作为分类页的子页面存在
解决方案
问题根源
你通过Link.state传递分类数据的方式不可靠:当用户直接输入分类URL、刷新页面,或者从商品页返回分类页时,location.state会丢失,导致解构失败。嵌套路由只是触发了这个隐藏问题,核心是数据获取方式错误。
修复步骤
- 修改分类页数据获取逻辑:不再依赖
location.state,改用URL参数:url匹配分类
const CategoryPage: React.FC = () => { // 获取URL中的分类url参数 const { url } = useParams<{ url: string }>(); const { products } = useSelector((state: RootState) => state.product); // 从分类数组(或redux/store)中匹配对应分类 const category = categories.find(cat => cat.url === url); // 处理分类不存在的情况 if (!category) { return <div>该分类不存在</div>; } const categoryProducts = products.filter(product => product.category.id === category.id); return ( <section> <h1>{category.name}</h1> <ProductCardList products={categoryProducts} /> </section> ); };
- 商品页通过URL参数获取数据:
const ProductPage: React.FC = () => { const { url: categoryUrl, id: productId } = useParams<{ url: string; id: string }>(); const { products } = useSelector((state: RootState) => state.product); const product = products.find(p => p.id === productId); if (!product) { return <div>该商品不存在</div>; } return ( <section> <h1>{product.name}</h1> {/* 商品详情内容 */} </section> ); };
- 路由配置保持不变:你之前的嵌套路由结构是正确的,无需调整
额外优化
- 添加异步数据加载状态:如果分类/商品是异步获取的,需在组件中处理loading状态,避免空值错误
- 新增404路由:在展示区路由末尾添加通配符路由,处理不存在的页面请求
内容的提问来源于stack exchange,提问作者qweezz
相关产品推荐
相关产品推荐

