Next.js宠物救助站项目:按钮跳转页面出现404错误求助
解决Next.js宠物详情页跳转404问题
你的问题主要出在路由文件结构不匹配、Link组件用法错误以及服务器组件与客户端钩子冲突这几个点,以下是分步解决方法:
1. 调整路由文件结构
首先确保详情页的文件路径和跳转路径严格对应:
- 若使用Pages Router(Next.js 12及更早,或13+兼容模式):将
PetDetailPage文件放在pages/adote/[petId].js - 若使用App Router(Next.js 13+):将
PetDetailPage放在app/adote/[petId]/page.js
这是404错误的核心原因——Next.js无法找到对应路径的页面组件。
2. 修正PetCard的Link组件
你当前用的是旧版Pages Router的as属性写法,且跳转路径和实际路由不匹配,改成直接指定动态路径:
import React from 'react'; import Image from 'next/image'; import Button from '../components/Button'; import Link from 'next/link'; export default function PetCard({ pet }) { return ( <div className="flex flex-col border p-4 rounded-lg hover:shadow-lg transition-shadow bg-white" > {/* 直接用pet.id作为动态参数,路径和路由文件对应 */} <Link href={`/adote/${pet.id}`}> <Button label="Ver perfil" className="bg-indigo-500 hover:bg-gray-600 focus-visible:outline-indigo-600 w-32 flex flex-row justify-center items-center" /> </Link> </div> ) }
- 去掉
passHref和onClick:Next.js 13+的Link组件可直接包裹按钮,无需额外属性;跳转逻辑由Link处理,不需要单独的onClick事件。
3. 修复PetDetailPage的逻辑
如果你用Pages Router:
去掉'use server'标识(useRouter是客户端钩子,不能在服务器组件中使用),并通过getServerSideProps获取宠物数据:
import React from 'react'; import { useRouter } from 'next/router'; import Image from 'next/image'; export default function PetDetailPage({ pet }) { if (!pet) return <p>宠物未找到</p>; return ( <div className="p-4"> <Image src={pet.avatar} alt={pet.name} width={600} height={600} className="rounded-md" /> <h1 className="text-2xl font-bold mt-4">{pet.name}</h1> <p className="text-gray-600">{pet.breed}</p> <p className="text-gray-600">{pet.id}</p> <p className="text-gray-600">{pet.age}</p> <p className="text-gray-600">{pet.gender}</p> <p className="mt-2">{pet.description}</p> </div> ); } // 服务器端获取宠物数据 export async function getServerSideProps(context) { const { petId } = context.query; try { const res = await fetch(`https://mockID.mockapi.io/pets/${petId}`); const pet = await res.json(); return { props: { pet } }; } catch (err) { return { props: { pet: null } }; } }
如果你用App Router:
添加'use client'标识(useParams是客户端钩子),通过useParams获取petId并请求数据:
'use client'; import React, { useState, useEffect } from 'react'; import { useParams } from 'next/navigation'; import Image from 'next/image'; export default function PetDetailPage() { const { petId } = useParams(); const [pet, setPet] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchPet = async () => { try { const res = await fetch(`https://mockID.mockapi.io/pets/${petId}`); const data = await res.json(); setPet(data); } catch (err) { setPet(null); } finally { setLoading(false); } }; fetchPet(); }, [petId]); if (loading) return <p>加载中...</p>; if (!pet) return <p>宠物未找到</p>; return ( <div className="p-4"> <Image src={pet.avatar} alt={pet.name} width={600} height={600} className="rounded-md" /> <h1 className="text-2xl font-bold mt-4">{pet.name}</h1> <p className="text-gray-600">{pet.breed}</p> <p className="text-gray-600">{pet.id}</p> <p className="text-gray-600">{pet.age}</p> <p className="text-gray-600">{pet.gender}</p> <p className="mt-2">{pet.description}</p> </div> ); }
4. 清理Adote页面的冗余代码
因为已经通过Link处理跳转,所以删掉Adote页面中无用的handlePetClick函数,以及PetCard的onClick传参:
// 删掉这段冗余代码 const handlePetClick = (petId) => { router.push(`/adote/${petId}`) } // PetCard调用改为 <PetCard key={pet.id} pet={pet} />
另外,Adote页面中你未导入router却使用了它,现在删掉相关代码后也无需再导入。
按以上步骤调整后,跳转和详情页展示就能正常工作了。
内容的提问来源于stack exchange,提问作者Tamara
相关产品推荐
相关产品推荐

