Next.js 13 App Router中如何同时使用PrismaClient与usePathname
解决Next.js 13 App Router中Header组件同时使用usePathname和Prisma的问题
核心矛盾在于:usePathname 只能在客户端组件中使用,而 PrismaClient 不能在浏览器环境运行,必须在服务端执行。解决思路是拆分组件,将数据获取和客户端交互逻辑分离:
步骤1:创建服务端组件获取分类数据
新建 HeaderServer.tsx,这是一个服务端组件(不需要加 'use client'),负责从数据库拉取分类数据,然后传递给客户端组件:
import { PrismaClient } from '@prisma/client' import HeaderClient from './HeaderClient' const prisma = new PrismaClient() export default async function HeaderServer() { const categories = await prisma.categories.findMany() return <HeaderClient categories={categories} /> }
步骤2:创建客户端组件处理导航激活状态
新建 HeaderClient.tsx,这是客户端组件(加 'use client'),接收服务端传来的分类数据,用 usePathname 判断当前激活的导航项:
'use client' import Link from 'next/link' import { usePathname } from 'next/navigation' type Category = { slug: string name: string } export default function HeaderClient({ categories }: { categories: Category[] }) { const pathname = usePathname() return ( <header> {categories.map((category) => { const href = `/${category.slug}` const isActive = pathname === href return ( <Link key={category.slug} href={href} className={isActive ? "menu-item item-active" : "menu-item"} > <span>{category.name}</span> </Link> ) })} </header> ) }
步骤3:在布局或页面中使用HeaderServer
在你的 layout.tsx 或其他页面文件中引入 HeaderServer 即可:
import HeaderServer from './HeaderServer' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <HeaderServer /> {children} </body> </html> ) }
原理说明
- 服务端组件
HeaderServer在服务器端执行,安全调用PrismaClient获取数据,不会将数据库连接逻辑暴露到浏览器。 - 客户端组件
HeaderClient只负责UI渲染和交互逻辑,通过props接收服务端传来的数据,使用usePathname判断当前路径实现激活状态标记。
内容的提问来源于stack exchange,提问作者philos
相关产品推荐
相关产品推荐

