You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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会丢失,导致解构失败。嵌套路由只是触发了这个隐藏问题,核心是数据获取方式错误。

修复步骤

  1. 修改分类页数据获取逻辑:不再依赖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>
  );
};
  1. 商品页通过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>
  );
};
  1. 路由配置保持不变:你之前的嵌套路由结构是正确的,无需调整

额外优化

  • 添加异步数据加载状态:如果分类/商品是异步获取的,需在组件中处理loading状态,避免空值错误
  • 新增404路由:在展示区路由末尾添加通配符路由,处理不存在的页面请求

内容的提问来源于stack exchange,提问作者qweezz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:01:13