MST
星途 面试题库

面试题:Next.js 嵌套路由中如何处理动态路由参数冲突问题

在 Next.js 的嵌套路由场景下,假设存在多层动态路由参数,例如 /parent/[parentId]/child/[childId],当两个动态参数名称相同或者在匹配逻辑上可能产生冲突时,应该如何解决?请描述解决方案及涉及到的关键代码片段。
42.4万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

解决方案

  1. 使用不同参数名
    • 最直接的方法是确保不同层级的动态路由参数使用不同的名称。例如,将 /parent/[parentId]/child/[childId] 改为 /parent/[parentId]/child/[subChildId]。这样可以避免名称冲突带来的歧义。
  2. 通过路由配置区分
    • 在 Next.js 中,可以利用 pages 目录结构来更清晰地定义路由。如果动态参数名称相同但匹配逻辑不同,可以通过目录层次和命名约定来区分。例如,在不同目录下定义相似名称的动态参数路由。假设在 pages/products/[productId]pages/categories/[categoryId],虽然参数名相似,但由于在不同目录结构下,它们的匹配逻辑是不同的。
  3. 自定义匹配逻辑
    • next.config.js 中可以通过 rewritesredirects 来定制路由匹配逻辑。
    • rewrites示例
      • 可以使用 rewrites 来重写请求路径,以避免冲突。
      module.exports = {
        async rewrites() {
          return [
            {
              source: '/parent/[parentId]/child/[childId]',
              destination: '/parent/:parentId/child/:childId'
            }
          ];
        }
      };
      
    • redirects示例
      • 如果需要将冲突的路由重定向到正确的页面,可以使用 redirects
      module.exports = {
        async redirects() {
          return [
            {
              source: '/old/[id]',
              destination: '/new/[id]',
              permanent: false
            }
          ];
        }
      };
      
  4. 在页面组件中处理
    • 在页面组件(如 pages/parent/[parentId]/child/[childId].js)中,可以通过 router.query 来获取动态参数,并根据业务逻辑进行处理。即使参数名称相同,也可以根据所在页面的上下文来区分它们的含义。
    • 例如:
    import { useRouter } from 'next/router';
    
    const ChildPage = () => {
      const router = useRouter();
      const { parentId, childId } = router.query;
      // 根据业务逻辑处理parentId和childId
      return (
        <div>
          <p>Parent ID: {parentId}</p>
          <p>Child ID: {childId}</p>
        </div>
      );
    };
    
    export default ChildPage;
    

关键代码片段:

  1. 使用不同参数名
    • 修改路由路径,例如从 /parent/[parentId]/child/[childId]/parent/[parentId]/child/[subChildId]
  2. 自定义匹配逻辑 - rewrites
    module.exports = {
      async rewrites() {
        return [
          {
            source: '/parent/[parentId]/child/[childId]',
            destination: '/parent/:parentId/child/:childId'
          }
        ];
      }
    };
    
  3. 自定义匹配逻辑 - redirects
    module.exports = {
      async redirects() {
        return [
          {
            source: '/old/[id]',
            destination: '/new/[id]',
            permanent: false
          }
        ];
      }
    };
    
  4. 在页面组件中处理
    import { useRouter } from 'next/router';
    
    const ChildPage = () => {
      const router = useRouter();
      const { parentId, childId } = router.query;
      return (
        <div>
          <p>Parent ID: {parentId}</p>
          <p>Child ID: {childId}</p>
        </div>
      );
    };
    
    export default ChildPage;