开发者问题收集

使用应用路由器将数据从一个页面传递到 Next.js 13 中的动态路由

2023-07-12
5600

问题陈述: 在带有应用路由器的 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>
3个回答

next/navigation 中的 router 不支持 query 参数。改用 useParams

调用为

<Link href={"/experimental/123"}>
    button
</Link>

接收为

export default function Page({ params }: { params: { id: string } }) {
    return <h1>{params.id}</h1>;
 }

另请参阅

  1. https://stackoverflow.com/a/76609568/13431819
  2. https://stackoverflow.com/a/76613628/13431819
krishnaacharyaa
2023-07-12

这是我在 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
Fer Toasted
2023-07-12

我使用 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;
Auvee
2023-07-13