如何让 NextJS 中的按钮转到我在同一应用程序中创建的另一个页面?

问题描述 投票:0回答:1

就上下文而言,我正在为宠物救援慈善机构建立一个网站,我正在使用 Next.js。 我是 Nextjs 的新手,不知道如何让我的按钮或链接正常工作 当我尝试使用按钮将我带到我在下一个应用程序中构建的另一个页面时,我当前收到 404 错误“找不到此页面”。

我尝试了一些方法。

有人可以帮忙吗??

这是卡片组件:

import React from 'react';
import Image from 'next/image';
import Button from '../components/Button';
import Link from 'next/link';

export default function PetCard({ pet, onClick }) {

  return (
    <div className="flex flex-col border p-4 rounded-lg hover:shadow-lg transition-shadow bg-white" >
      <Link href="/[petId]" as={`/adote/${pet.name}`} passHref>
        <Button
          label="Ver perfil"
          onClick={onClick}
          className="bg-indigo-500 hover:bg-gray-600 focus-visible:outline-indigo-600 w-32 flex flex-row justify-center items-center"
        /></Link>

    </div>
  )
}

该按钮应该转到此 petId 页面:

'use server'
import React from 'react';
import { useRouter } from 'next/router';


export default function PetDetailPage() {
  const router = useRouter();
  const pet = JSON.parse(router.query);
 
  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>
  );
}

我不介意它现在是否只是一个占位符页面。我从我制作的模拟 api 中获取了这些模拟数据,并且在主要采用页面上获取时没有任何问题:

'use client';

import React from 'react';
import CustomizableHero from "../../components/HeroScondary";
import PetCard from "../../components/PetCard";
import Button from '../../components/Button';
import { useState, useEffect } from 'react'

export default function Adote() {
  // mock API
  const [pets, setPets] = useState([])
  const [loading, setLoading] = useState(true)
  const [page, setPage] = useState(1)

  useEffect(() => {
    const fetchPets = async () => {
      setLoading(true)
      const url = new URL('https://653bf08fd5d6790f5ec7a989.mockapi.io/pets')

      url.searchParams.append('completed', false)
      url.searchParams.append('page', page)
      url.searchParams.append('limit', 18)
      
      const res = await fetch(url)      
      const data = await res.json()
      setPets(prevPets => [...prevPets, ...data])
      setLoading(false)

    }
    fetchPets()
  },
    [])

  if (loading) {
    return <p>Loading...</p>
  }

  const handlePetClick = (petId) => {
    router.push(`/adote/${petId}`)
  }

  return (
    <div className="relative">
      <CustomizableHero
        backgroundImage="/images/dois-cachorros.png"
        title="Adote"
        subtitle="Encontre o seu melhor amigo"
        color="white"
      />
      {/* search filter */}
      <div className="flex flex-row">
      </div>
      {/* pet cards */}
      <div className="absolute w-[100vw] max-w-screen flex flex-col justify-center ">
        <div className="flex flex-col text-align-center items-center justify-between m-10">
          <h2 className="text-5xl font-bold tracking-tight sm:text-5xl text-gray-500 p-5">Animais buscando uma familia</h2>
          <p className="mt-6 mb-3 text-md leading-8 text-gray-500 text-center p-5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nulla ut condimentum maximus, felis enim rhoncus justo, vel venenatis magna tortor nec tortor. Donec vulputate fermentum fermentum. Curabitur odio dui, consectetur vitae ornare eu, ultricies vel risus</p>
        </div>
        {/* Called displayPetCards() inside JSX code to render the PetCard components. */}
        <div className="grid grid-cols-3 gap-4 m-10 p-5">
          {pets.map(pet => (
            <PetCard
              key={pet.id}
              pet={pet}
              onClick={()=> handlePetClick(pet.id)}
            />
          ))}
        </div>
        <p className="flex flex-col text-center mt-5">Visualizados 18 de 661 animais de estimação</p>
        <div className="flex justify-center m-10">
          <Button
            label="Mostrar mais"
            onClick={() => setPage(page + 1)
            }  // Attach the click handler here
            className="bg-indigo-500 hover:bg-gray-600 focus-visible:outline-indigo-600"
          />
        </div>
      </div>
    </div>
  );
};

我尝试过 useRouter,我尝试过 getServerSideProps() 但没有任何效果

javascript button next.js next.js13
1个回答
0
投票

这是我制作的示例代码: 说明:

  • 有一个宠物页面,显示所有宠物的名字,
  • 它包含 2 个元素
    1st is Link tag
    &
    2nd is a Button as link
  • 看一下文件夹结构,焦点
    pets folder
  • 在宠物页面上,我已经使用代码中存在的 URL 显示了宠物数据(您可以使用您的卡片组件显示它)。

文件夹结构:

projectName
├── .gitignore
├── jsconfig.json
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   ├── images
│   ├── next.svg
│   └── vercel.svg
├── README.md
├── src
│   └── app
│       ├── api
│       ├── comp
│       │   ├── LinkButton.js
│       ├── favicon.ico
│       ├── globals.css
│       ├── layout.js
│       ├── page.js
│       ├── pets
│       │   ├── page.js
│       │   └── [id]
│       │       └── page.js
└── tailwind.config.js
  • 现在我将显示宠物数据,并从中将 ID 传递给链接标签和按钮组件。

  • 按钮组件是事件点击的客户端 bcoz。

  • 现在,如果有人点击链接或按钮,他们将被导航到

    pets/id

  • 使用代码中存在的 url,我在其中附加了 id,通过 id 获取宠物的详细信息。详细信息页面位于文件夹

    pets/[id]/page.js

您可以阅读本文以获得更清晰的概念

所有宠物详细信息页面:

projectName\src\app\pets\page.js

import Link from "next/link"
import LinkButton from "../comp/LinkButton"

async function GetPets() {
    let data = await fetch('https://653bf08fd5d6790f5ec7a989.mockapi.io/pets')
    let PetsData = await data.json()
    // console.log(PetsData);
    // LOGGED IN TERMINAL BCOZ ITS SERVER-SIDE

    return PetsData
}

export default async function Pets() {


    const PetsData = await GetPets()

    return (
        <div>
            <h1>All Pets !</h1>
            {
                PetsData.map((p, i) => {
                    return (
                        <div style={{
                            border: "1px solid black",
                            padding: "25px",
                            margin: '25px'
                        }}
                            key={i}
                        >
                            <img src={p.avatar} width="250" alt="" />
                            <h3>{p.name}</h3>
                            <Link style={{ color: "blue" }} href={`/pets/` + p.id}> VIew </Link>

                            <LinkButton ID={p.id} />
                        </div>
                    )
                })
            }

        </div>
    )
}

宠物详细信息页面:

projectName\src\app\pets\[id]\page.js

async function GetDetailsByID(ID) {
    let data = await fetch('https://653bf08fd5d6790f5ec7a989.mockapi.io/pets/' + ID)

    // I GOT THIS URL BY TRYING TO APPEND ID TO URL PROVIDED IN CODE

    let PetDetails = await data.json()
    // console.log(Object.keys(PetDetails));
    // LOGGED IN TERMINAL BCOZ ITS SERVER-SIDE


    return PetDetails
}

export default async function DetailsPage({ params }) {
    let Details = await GetDetailsByID(params.id)
    // AFTER GETTING ID I WILL PASS IT THE API CALL

    // THIS PAGE WILL BE SERVER RENDERED

    return (
        <div>
            <h1>Full Pet Deyails :</h1>
            <img src={Details.avatar} alt="" />
            <p className="text-gray-600">{Details.name}</p>
            <p className="text-gray-600">{Details.id}</p>
            <p className="text-gray-600">{Details.age}</p>
            <p className="text-gray-600">{Details.Gender}</p>
            <p className="text-gray-600">{Details.breed}</p>
            <p className="text-gray-600">{Details.description}</p>
            <p className="text-gray-600">{Details.createdAt}</p>




        </div>
    )
}

LinkButton.js 组件

projectName\src\app\comp\LinkButton.js
comp 文件夹下

'use client'
import { useRouter } from 'next/navigation'
import React from 'react'

const LinkButton = ({ ID }) => {
    const MyRouter = useRouter()

    // IF YOU WANT TO USE A BUTTON THEN IT COMES UNDER CLIENT SIDE 
    // RENDERING BECAUSE OF CLICK EVENT


    // HERE IM PASSING THE ID TO LINK & USING ROUTER TO NAVIGATE
    return (
        <button onClick={() => {
            MyRouter.push(`/pets/` + ID)
        }}>
            Button
        </button>
    )
}

export default LinkButton

您可以将链接标签设置为看起来像按钮,而不是使用按钮!

输出:

  1. 转到http://localhost:3000/pets
  2. 您将看到一个类似卡片的布局,链接标签名为“视图”,蓝色,按钮名为“按钮”。
  3. 单击它们,您将进入一个页面。第一个宠物被点击
    http://localhost:3000/pets/1
  4. 在此页面上,详细信息是通过 ID 获取的。
  5. 打开控制台,然后
    open Network Tab
    单击
    pets
    ,然后在右侧单击预览,您将看到页面已预渲染!
  6. 同样对于详细信息页面,您将在
    Network Tab
    中单击预览,您将看到页面已预渲染。

如有疑问请评论。

此代码将从我这边删除。

© www.soinside.com 2019 - 2024. All rights reserved.