Next.js/React中如何实现服务端渲染列表项的点击功能?
解决方案:拆分服务端与客户端组件实现交互
你不需要把整个StemList转为客户端组件,Next.js支持服务端组件嵌套客户端组件,刚好适配你的场景:服务端组件负责数据库查询和列表渲染,把需要交互的单个歌曲项抽成客户端组件处理点击事件。
步骤1:创建客户端交互组件
新建一个StemItem.js文件,添加'use client'指令声明为客户端组件,接收歌曲数据并绑定点击事件:
'use client'; export default function StemItem({ stem }) { const handleClick = () => { console.log(`歌曲名:${stem.song_name},艺术家:${stem.artist_name}`); }; return ( <ul className='song-title' onClick={handleClick}> {stem.song_name} - {stem.artist_name} </ul> ); }
步骤2:修改原服务端组件
在StemList中引入刚才的客户端组件,把原来的列表项替换成StemItem,传递歌曲数据即可:
import prisma from "@/components/stemdatabase"; import StemItem from './StemItem'; // 引入客户端组件 export async function getStems(stemType) { return prisma.stems.findMany({ where: { stem_type: stemType } }); } export default async function StemList({ stemType }) { const stems = await getStems(stemType); return ( <> {stems.map((stem) => ( <StemItem key={stem.id} stem={stem} /> ))} </> ); }
方案说明
StemList依旧是服务端组件,保留Prisma数据库查询能力,避免客户端查询带来的性能和安全问题。StemItem作为客户端组件,拥有完整的React交互能力,能正常使用onClick等事件属性。- Next.js 13+的App Router原生支持服务端组件与客户端组件的嵌套组合,这是官方推荐的拆分模式。
内容的提问来源于stack exchange,提问作者jeff shell
相关产品推荐
相关产品推荐

