You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中点击组件向目标页面传递Props的最优方案

在Next.js中实现PlaylistItem到/difficulty页面的参数传递

下面给你几种可行的实现方式,以及各自的优劣,你可以根据项目需求选最优的:

1. URL查询参数(最直接易实现)

直接在PlaylistItem的href里拼接查询参数,把需要的id、playlistName等传过去,注意对含特殊字符的参数做编码处理,避免URL解析错误:

修改PlaylistItem的代码:

function PlaylistItem({playlistName,id,description,background} : { playlistName : string, id : string, description : string, background : string}) {
  const encodedName = encodeURIComponent(playlistName);
  const encodedDesc = encodeURIComponent(description);

  return (
    <a 
      className='flex-col justify-center flex text-center items-center cursor-pointer mb-6' 
      href={`/difficulty?id=${id}&name=${encodedName}&desc=${encodedDesc}`}
    >
      <div className=' w-[100px] h-[100px] rounded-full' style={{backgroundImage: `url(${background})`,backgroundPosition:"center",backgroundSize:"cover"}}></div>
      <p className='mt-2'>{playlistName}</p>
    </a>
  )
}

export default PlaylistItem

在/difficulty页面获取参数:

  • 客户端组件用useRouter:
'use client'
import { useRouter } from 'next/navigation';

export default function DifficultyPage() {
  const searchParams = new URLSearchParams(window.location.search);
  const id = searchParams.get('id');
  const playlistName = decodeURIComponent(searchParams.get('name') || '');
  const description = decodeURIComponent(searchParams.get('desc') || '');

  return (
    <div>
      <h1>Playlist: {playlistName}</h1>
      <p>ID: {id}</p>
      <p>Description: {description}</p>
    </div>
  )
}
  • 服务端组件直接用searchParams props:
export default function DifficultyPage({ searchParams }: { searchParams: { id?: string; name?: string; desc?: string } }) {
  const id = searchParams.id;
  const playlistName = searchParams.name ? decodeURIComponent(searchParams.name) : '';
  const description = searchParams.desc ? decodeURIComponent(searchParams.desc) : '';

  return (
    <div>
      <h1>Playlist: {playlistName}</h1>
      <p>ID: {id}</p>
      <p>Description: {description}</p>
    </div>
  )
}

这种方式优点是实现简单,无需修改路由结构;缺点是URL会携带一堆参数,不够美观,参数过多时会显得杂乱。

2. 动态路由+查询参数(更语义化)

如果想让URL更友好,可用动态路由承载核心参数(比如id),其他可选参数用查询参数补充,甚至可以直接通过id从API拉取完整数据,避免冗余参数暴露在URL中。

第一步,创建动态路由文件:App Router用app/difficulty/[playlistId]/page.tsx,Pages Router用pages/difficulty/[playlistId].tsx。

修改PlaylistItem的href:

function PlaylistItem({playlistName,id,description,background} : { playlistName : string, id : string, description : string, background : string}) {
  // 若可通过id查API获取其他数据,可只传id:href={`/difficulty/${id}`}
  const encodedName = encodeURIComponent(playlistName);
  return (
    <a 
      className='flex-col justify-center flex text-center items-center cursor-pointer mb-6' 
      href={`/difficulty/${id}?name=${encodedName}`}
    >
      <div className=' w-[100px] h-[100px] rounded-full' style={{backgroundImage: `url(${background})`,backgroundPosition:"center",backgroundSize:"cover"}}></div>
      <p className='mt-2'>{playlistName}</p>
    </a>
  )
}

在动态路由页面获取参数:

  • App Router(服务端组件):
export default async function DifficultyPage({ params, searchParams }: { 
  params: { playlistId: string },
  searchParams: { name?: string }
}) {
  const playlistId = params.playlistId;
  const playlistName = searchParams.name ? decodeURIComponent(searchParams.name) : '';

  // 可选:通过id调用API获取完整数据
  // const playlistData = await fetch(`/api/playlists/${playlistId}`).then(res => res.json());

  return (
    <div>
      <h1>Playlist: {playlistName}</h1>
      <p>ID: {playlistId}</p>
    </div>
  )
}
  • Pages Router:
import { useRouter } from 'next/router';

export default function DifficultyPage() {
  const router = useRouter();
  const { playlistId } = router.query;
  const playlistName = router.query.name ? decodeURIComponent(router.query.name as string) : '';

  return (
    <div>
      <h1>Playlist: {playlistName}</h1>
      <p>ID: {playlistId}</p>
    </div>
  )
}

// 也可用getServerSideProps获取参数并预取数据
export async function getServerSideProps(context) {
  const { playlistId } = context.params;
  const { name } = context.query;
  const decodedName = name ? decodeURIComponent(name) : '';

  return {
    props: {
      playlistId,
      playlistName: decodedName
    }
  }
}

这种方式优点是URL更美观(比如/difficulty/123),语义性更强;若通过id拉取数据,还能避免参数被篡改,数据准确性更高。缺点是需要调整路由结构,多参数场景仍需结合查询参数。

3. 状态管理(不推荐跨页面使用)

比如用React Context、Redux等把数据存在全局状态,点击PlaylistItem时先存状态再跳转。但这种方式存在致命问题:页面刷新后状态会丢失,用户直接访问/difficultyURL时会因无数据导致页面异常,仅适合临时客户端状态传递,不适合跨页面跳转场景。

最优方案选择

  • 若参数少、对URL美观度无要求,直接用查询参数即可,快速实现。
  • 若想URL更友好,或可通过id从API获取完整数据,优先选动态路由+按需查询参数,更符合Next.js路由设计,也更健壮。

内容的提问来源于stack exchange,提问作者Bonhart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:25:24