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

Next.js嵌套动态路由跳转偶现undefined参数问题排查

问题背景

项目目录结构

shop
 - [categorySlug]
   - [productSlug]
     - index.tsx
   - index.tsx
index.tsx

正常路由示例

  • /shop/shoes/nike-1
  • /shop/jersey/jersey-1

问题复现代码

[categorySlug]目录下的index.tsx代码如下:

export function ShopCategoryComponent({ products }): JSX.Element {
  const { query } = useRouter();
  const router = useRouter();
  const categorySlug = hasCategorySlug(query) ? query.categorySlug : undefined;

  const viewProductDeatails = useCallback(
    (productSlug) => {
      router.push(`/shop/${categorySlug}/${productSlug}`);
    },
    [router]
  );

  return (
    <section>
      {products.map((product) => (
        <div
          key={`${product.id}`}
          onClick={() => viewProductDeatails(product.slug)}
        >
          <h3>{product.name}</h3>
          <h3>{product?.$on['SimpleProduct'].price()}</h3>
          <img src={product?.$on['SimpleProduct'].image.sourceUrl()} />
        </div>
      ))}
    </section>
  );
}

export default function ShopCategory() {
  const { useQuery } = client;
  const { query } = useRouter();
  const { products } = useQuery();
  const categorySlug = hasCategorySlug(query) ? query.categorySlug : undefined;
  const generalSettings = useQuery().generalSettings;

  const setProducts = products({
    where: {
      categoryIn: categorySlug,
    },
  }).nodes;

  return (
    <React.Fragment>
      <Menu />
      <main className='content content-single'>
        <ShopCategoryComponent products={setProducts} />
      </main>
      <Footer copyrightHolder={generalSettings.title} />
    </React.Fragment>
  );
}

预期逻辑:点击商品卡片/图片后,跳转到对应[productSlug]的商品详情页。实际偶发跳转异常,路径为/shop/shoes/undefined。

错误原因

一共有两处逻辑问题,第二点是直接触发该异常的核心原因:

  1. useCallback依赖缺失,存在闭包陷阱
    viewProductDeatails函数内部使用了categorySlug变量,但useCallback的依赖数组只传入了router,没有把categorySlug加入依赖。Next.js客户端水合初期,useRouter()返回的query是空对象,此时categorySlug值为undefined,useCallback会缓存这个初始状态生成的函数;等后续路由参数解析完成,因为没有声明对应依赖,缓存的函数不会更新,会触发/shop/undefined/xxx类的跳转异常。
  2. 异步数据无加载兜底、字段取值缺少校验
    你调用的GraphQL商品查询是异步接口,首次渲染时接口还未返回数据,setProducts拿到的nodes是带空值的占位数组,数组内的商品项还未填充slug字段;另外渲染商品价格、图片时你给SimpleProduct字段加了可选链?.做兜底,但是点击事件取product.slug时没有做任何非空判断,直接把可能为undefined的slug传入跳转方法,最终拼接出来的路径最后一段就会出现undefined,也就是你遇到的/shop/shoes/undefined问题。
修复方式
  • 补全useCallback依赖数组,把categorySlug加入依赖项;
  • 增加加载态判断,商品数据未返回完成时,不渲染可点击的商品卡片;
  • 跳转逻辑增加参数校验,传入的productSlug为空时直接return不执行路由跳转;
  • 商品字段取值统一加可选链兜底,比如取slug时写product?.slug,避免直接读取undefined属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:42:16