使用应用路由器将数据从一个页面传递到 Next.js 13 中的动态路由
问题陈述: 在带有应用路由器的 NextJS 13 中,我想将数据从 “/experimental” 传递到动态路由 “/experimental/${id}” 。它给了我 'router.query' ,因为它未定义。有没有更好的方法?
我尝试在带有应用路由器的 nextjs 13 中使用 'next/navigation' 。我无法将数据从一个组件传递到另一个组件。
这是我的 Json 数据
draft.js
export const draft = [
{
id: 1,
title: "Burkina Faso serve Togo Vincent student",
imageUrl: "/cards/1.jpg",
imageType: "single image",
price: 8000,
buttonText: "View Design",
cardType: "Single Page",
popularity: 1,
cardCategory: "singlePageCard",
},
];
export default draft;
这是我的 ExperimentCard,我在其中传递和映射 Draft.js 数据对象
import Cards from "../../components/Cards/Cards";
import { draft } from "../../Data/Draft_Data";
const ExperimentalCard = () => {
return (
<div className="ml-[1rem] md:ml-14">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-10 min-h-[120vh]">
{draft.map((item, index) => (
<Cards key={index} items={item} />
))}
</div>
</div>
);
};
export default ExperimentalCard;
并且 Card 组件会喜欢这个。我想从 Cards 组件将数据传递到动态路由 "/experimental/${id}" 。
Cards.jsx
'use client'
import { useRouter } from 'next/navigation'
import React from "react";
const Cards = ({ items }) => {
const router = useRouter()
const handleCardClick = (id) => {
router.push(`/experimental/${id}`);
};
return (
<div>
<div className="mx-5 lg:mx-10">
<div
className="w-full h-[30rem] md:h-[25rem] lg:h-[20rem] items-center bg-contain bg-no-repeat"
style={{ backgroundImage: `url('${items.imageUrl}')` }}
onClick={() => handleCardClick(item.id)}
>
<div className="bg-[#23272a93] relative z-0 w-32 mb-4 ml-4 h-11 text-center items-center flex rounded-sm justify-center ">
<p className="text-base-100 uppercase">{items.cardType}</p>
</div>
</div>
<div className="flex flex-row mt-4 justify-between">
<h2 className="font-normal text-[1.5rem] md:text-[1.4rem] lg:text-xl basis-2/3">
{items.title}
</h2>
<p className="font-bold text-2xl lg:text-xl basis-1/3 text-right md:text-left lg:text-right">
৳{items.price}
</p>
</div>
{/* <p>Popularity: {items.popularity}</p> */}
</div>
</div>
);
};
export default Cards;
单击组件时,它将导航到动态链接 "/experimental/${id}" 。它给出了一个错误
[id]/page.jsx
'use client'
import { useRouter } from 'next/navigation'
import React from 'react'
const Page = () => {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>Experimental Card Details</h1>
<p>Card ID: {id}</p>
<p>Card title: {title}</p>
<p>Card imageUrl: {imageUrl}</p>
<p>Card imageType: {imageType}</p>
<p>Card price: {price}</p>
<p>Card buttonText: {buttonText}</p>
<p>Card cardType: {cardType}</p>
<p>Card popularity: {popularity}</p>
<p>Card cardCategory: {cardCategory}</p>
</div>
);
}
export default Page
未处理的运行时错误 TypeError:无法解构“router.query”的属性“id”,因为它未定义。
src\app\experimental\[id]\page.jsx (7:10) @ id
5 | const Page = () => {
6 | const router = useRouter();
> 7 | const { id } = router.query;
| ^
8 |
9 | return (
10 | <div>
next/navigation
中的
router
不支持
query
参数。改用
useParams
。
调用为
<Link href={"/experimental/123"}>
button
</Link>
接收为
export default function Page({ params }: { params: { id: string } }) {
return <h1>{params.id}</h1>;
}
另请参阅
这是我在 App 路由器中处理参数和查询的方式
你的情况
export default async function Page({
// your dynamic value in this case [id]
params
})
如果你有 searchParams,例如
[id]?ref=foo-bar
typescript:
export default async function Page({
// dynamic route params
params,
searchParams,
}: {
// [id] in your case
params: { id: string };
searchParams: { ref: string };
})
查看 NextJs 文档 了解详情
你的实现应该是这样的
// note that this will be a RSC, therefore no need for 'use client' directive
import React from 'react'
const Page = ({ params }) => {
const id = params.id
return (
<div>
<h1>Experimental Card Details</h1>
<p>Card ID: {id}</p>
</div>
);
}
export default Page
我使用 useParams 在
“[id]/page.jsx”
-> 组件中解决了这个问题,
“experimental/${id}”
-> 路由
我只需从路由中获取 id,然后在本地 json 中执行 find 操作即可获取单张卡片数据。
这是我的 [id]/page.jsx 动态路由代码
"use client";
import React from "react";
import { draft } from "../../../Data/Draft_Data";
import { useParams } from "next/navigation";
const Page = () => {
const params = useParams();
const card = draft.find((item) => item.id === parseInt(params.id));
return (
<div>
<h1>Experimental Card Details</h1>
{card ? (
<>
<p>Card ID: {card.id}</p>
<p>Card title: {card.title}</p>
</>
) : (
<p>Card not found.</p>
)}
</div>
);
};
export default Page;