英文:
Passing data from one page to a dynamic route in Next.js 13 with app router
问题
在NextJS 13中使用应用程序路由器(app router),我想从"/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
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>
</div>
</div>
);
};
export default Cards;
当我点击组件时,它将导航到动态链接"/experimental/${id}"。但是它给我一个错误:
[id]/page.jsx
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',因为它未定义。
希望这可以帮助您解决问题。
英文:
Problem Statement: In NextJS 13 with app router, I want to pass data from "/experimental" to dynamic route "/experimental/${id}". It gives me 'router.query' as it is undefined. Is there any better approach?
I tried using 'next/navigation' in the nextjs 13 with app router. I can't pass the data to one component to another.
Here is my Json data
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;
Here is my ExperimentCard where I pass and mapping the Draft.js data object
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;
And the Card components will like this. And From Cards Components I want to pass data to dynamic route "/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;
When I click the component it will navigate to the dynamic link "/experimental/${id}". It gives me an error
[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
Unhandled Runtime Error TypeError: Cannot destructure property 'id' of 'router.query' as it is undefined.
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>
答案1
得分: 1
这是我在应用程序路由器中处理参数和查询的方式
你的情况
export default async function Page({
// 在这种情况下,您的动态值是[id]
params
})
如果您有searchParams,例如[id]?ref=foo-bar
TypeScript:
export default async function Page({
// 动态路由参数
params,
searchParams,
}: {
// 在您的情况下是[id]
params: { id: string };
searchParams: { ref: string };
})
请查看Next.js文档以获取详细信息
您的实现应该如下所示
// 请注意,这将是一个RSC,因此不需要'use client'指令
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
英文:
This is how I handle params and queries in the App router
your case
export default async function Page({
// your dynamic value in this case [id]
params
})
In case you have searchParams eg [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 };
})
Check the NextJs documentation for details
You implementation should be like this
// 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
答案2
得分: 1
在 `next/navigation` 中,`router` 不支持 `query` 参数。请改用 `useParams`。
调用方式:
```jsx
<Link href={"/experimental/123"}>
button
</Link>
接收方式:
export default function Page({ params }: { params: { id: string } }) {
return <h1>{params.id}</h1>;
}
另请参考:
<details>
<summary>英文:</summary>
`router` in `next/navigation` doesn't support `query` parameter. Use `useParams` instead.
Invoke as
<Link href={"/experimental/123"}>
button
</Link>
Receive as
export default function Page({ params }: { params: { id: string } }) {
return <h1>{params.id}</h1>;
}
Also refer
1. https://stackoverflow.com/a/76609568/13431819
2. https://stackoverflow.com/a/76613628/13431819
</details>
# 答案3
**得分**: 1
I solved it with **useParams** in
**"[id]/page.jsx"** -> 组件,
**"experimental/${id}"** -> 路由
I just get the id from the Route then perform find operation in my local json to get the single card data.
Here is my Dynamic Route Code for **[id]/page.jsx**
```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;
英文:
I solved it with useParams in
"[id]/page.jsx" -> component,
"experimental/${id}" -> route
I just get the id from the Route then perform find operation in my local json to get the single card data.
Here is my Dynamic Route Code for [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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论