Next.js:如何根据Link的href为[slug].tsx动态传递Props
Next.js 动态传递Props到[slug].tsx页面的解决方案
问题背景
在Next.js应用的[slug].tsx页面中,当前通过硬编码serie[0]渲染Collection组件,路由跳转功能正常,但需要根据用户点击的Link链接(如collection/1、collection/2)动态匹配对应的数据并传递给组件。
现有代码
Link组件代码
<Link href="collection/1" className="row-start-1 row-end-3"> <Image src={serie[0].image} width={1000} height={1000} alt="pic1" style={{ height: "100%", width: "100%" }} /> </Link> <Link href="collection/2" className="row-start-1 row-end-2"> <Image src={serie[1].image} width={1000} height={1000} alt="pic2" /> </Link>
[slug].tsx页面代码
import { serie } from "../../data/serie"; import Collection from "../../src/Collection"; const CollectionPage = () => { return <Collection description={serie[0].description} img={serie[0].image} />; }; export default CollectionPage;
解决方案
根据你使用的Next.js路由方案(Pages Router / App Router),分别提供实现方式:
方案一:Pages Router(Next.js 12及更早版本)
方式1:使用useRouter钩子实时获取参数
修改[slug].tsx页面,通过路由钩子获取当前的slug值,再匹配对应的数据项:
import { useRouter } from 'next/router'; import { serie } from "../../data/serie"; import Collection from "../../src/Collection"; const CollectionPage = () => { const router = useRouter(); // 获取URL中的slug参数(如"1"、"2") const { slug } = router.query; // 匹配对应的数据(注意slug是字符串,需转为数字) const currentItem = serie.find(item => item.id === Number(slug)); // 处理数据不存在的情况 if (!currentItem) return <div>该内容不存在</div>; return <Collection description={currentItem.description} img={currentItem.image} />; }; export default CollectionPage;
方式2:静态生成页面(推荐)
使用getStaticPaths和getStaticProps预生成所有可能的页面,性能更优:
import { serie } from "../../data/serie"; import Collection from "../../src/Collection"; // 预生成所有动态路径 export async function getStaticPaths() { const paths = serie.map(item => ({ params: { slug: item.id.toString() } })); return { paths, fallback: false }; } // 获取对应路径的数据 export async function getStaticProps({ params }) { const { slug } = params; const currentItem = serie.find(item => item.id === Number(slug)); return { props: { currentItem } }; } const CollectionPage = ({ currentItem }) => { if (!currentItem) return <div>该内容不存在</div>; return <Collection description={currentItem.description} img={currentItem.image} />; }; export default CollectionPage;
方案二:App Router(Next.js 13+)
如果你的项目使用App Router,修改app/collection/[slug]/page.tsx文件:
import { useParams } from 'next/navigation'; import { serie } from "../../../data/serie"; import Collection from "../../../src/Collection"; // 可选:预生成所有静态页面 export async function generateStaticParams() { return serie.map(item => ({ slug: item.id.toString(), })); } export default function CollectionPage() { const params = useParams(); const slug = params.slug as string; const currentItem = serie.find(item => item.id === Number(slug)); if (!currentItem) return <div>该内容不存在</div>; return <Collection description={currentItem.description} img={currentItem.image} />; }
注意事项
- 确保你的
serie数据数组中每个元素都包含id字段(值为1、2等,与Link的href参数对应)。 - 如果需要循环渲染多个Link组件,建议遍历
serie数组动态生成,避免硬编码:{serie.map(item => ( <Link key={item.id} href={`collection/${item.id}`} className="your-class"> <Image src={item.image} width={1000} height={1000} alt={`pic${item.id}`} style={{ height: "100%", width: "100%" }} /> </Link> ))}
内容的提问来源于stack exchange,提问作者Piet
相关产品推荐
相关产品推荐

