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

Next.js动态页面导航出现404错误求助排查

Next.js动态页面导航404问题修复

问题核心

开发车辆详情动态页时,点击列表页链接跳转后始终返回404,无其他报错。尝试将_id类型改为字符串后,VSCode保存时会自动恢复为number类型。

代码分析与问题点

1. 动态路由文件结构错误

Next.js App Router要求动态路由必须遵循app/[路由段]/page.tsx的结构。如果车辆详情页未放在app/vehicles/[vehicleId]/page.tsx路径下,会直接返回404。

2. 类型定义不匹配

Vehicle类型中_id被定义为number,但后端API返回的_id(通常是MongoDB的ObjectId)是字符串类型。这会导致:

  • 链接拼接时vehicle._id(number)转字符串可能出现格式问题
  • VSCode的类型检查或格式化工具(如Prettier)会自动将手动修改的string类型恢复为number

3. 数据获取与组件渲染不匹配

  • getVehicleDetail函数获取的是单个车辆数据,但VehicleDetails组件却按数组处理,调用map方法会导致渲染异常
  • VehiclePage传递给VehicleDetails的是单个车辆的Promise,却被当作数组Promise接收

修复步骤

步骤1:确认动态路由文件结构

确保项目目录结构如下:

app/
├── vehicles/
│   ├── [vehicleId]/
│   │   └── page.tsx  # 车辆详情页必须放在此路径下
└── ...

步骤2:修正类型定义

将Vehicle类型的_id改为string,匹配API返回的ObjectId格式:

// 修正后的Vehicle类型
type Vehicle = {
  _id: string;
  name: string;
  pictures: string;
  description: string;
  colour: string;
  transmission: string;
  type: string;
  seat: number;
  price: number;
  date: string;
  createdBy: string;
};

解决VSCode自动恢复类型的问题

检查项目中的Prettier或TypeScript配置:

  • 若为Prettier自动格式化导致,可在.prettierrc中添加规则禁用类型自动修改
  • 若为TypeScript类型推断问题,给getVehicleDetail明确添加返回类型标注:
export default async function getVehicleDetail(vehicleId: string): Promise<Vehicle | undefined> {
  const res = await fetch(
    `https://brainy-clothes-fish.cyclic.app/api/v1/vehicles/${vehicleId}`,
    { next: { revalidate: 60 } }
  );

  if (!res.ok) return undefined;
  return res.json() as Promise<Vehicle>;
}

步骤3:修正组件数据处理逻辑

修正VehicleDetails组件

因为获取的是单个车辆,无需map数组,直接渲染单条数据:

type Props = {
  vehicle: Vehicle | undefined;
};

export default function VehicleDetails({ vehicle }: Props) {
  if (!vehicle) return <div>车辆不存在</div>;

  return (
    <article>
      <h2>{vehicle.name}</h2>
      {/* 其他车辆信息渲染 */}
    </article>
  );
}

修正VehiclePage组件

直接获取单个车辆数据,传递给VehicleDetails:

import getVehicleDetail from "@/lib/getVehicleDetails";
import VehicleDetails from "./components/VehicleDetails";

type Params = {
  params: {
    vehicleId: string;
  };
};

export default async function VehiclePage({ params: { vehicleId } }: Params) {
  const vehicle = await getVehicleDetail(vehicleId);
  return <VehicleDetails vehicle={vehicle} />;
}

步骤4:确认列表页链接正确性

给列表项添加唯一key,确保链接拼接正确:

// HomeMainBody组件中
{vehicles.map((vehicle) => {
  return (
    <div key={vehicle._id}>
      <VehicleCard vehicle={vehicle} />
      <Link href={`/vehicles/${vehicle._id}`}>{vehicle.name}</Link>
    </div>
  );
})}

验证修复

  1. 重启Next.js开发服务器
  2. 点击列表页车辆链接,确认能正常跳转并展示详情数据
  3. 若VSCode仍自动修改类型,可在类型定义处添加// @ts-ignore临时忽略,或调整IDE格式化设置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:37:35