Next.js + Prisma 博客文章浏览量不更新问题求助
问题:Next.js + Prisma博客文章浏览量无法递增
我正在使用Next.js和Prisma开发一个博客应用,在根据ID展示文章的详情页中,希望每次页面被获取时递增浏览量,但浏览量完全没有变化。
我尝试过在递增浏览量前获取文章、递增后获取文章,甚至使用带select的update语句一步完成获取与递增,但这些方案都无效。我没有在每次请求时创建新的Prisma Client实例,数据库连接稳定,更新浏览量时也没有抛出任何错误。
相关代码
page.tsx
import BackButton from "@/components/BackButton"; import Badge from "@/components/Badge"; import DeleteButton from "@/components/DeleteButton"; import Like from "@/components/Like"; import Views from "@/components/Views"; import { Tag } from "@prisma/client"; import { Pencil } from "lucide-react"; import Link from "next/link"; interface Props { params: { id: string; }; } interface Post { id: string; title: string; content: string; tag: Tag; views: number; likes: number; } const getPost = async ({ params }: Props): Promise<Post> => { const res = await fetch(`http://localhost:3000/api/posts/${params.id}`, { cache: "no-store", }); return res.json(); }; const DetailPage = async ({ params }: Props) => { const post = await getPost({ params }); return ( <div className="flex flex-col gap-4 max-w-lg"> <BackButton href="/posts" /> <div className="flex justify-between gap-1 items-baseline max-w-sm"> <h1 className="text-3xl font-bold">{post.title}</h1> {post.tag && <Badge tag={post.tag.name} />} </div> <div className="flex justify-start gap-4 items-baseline max-w-sm"> <div className="flex items-center gap-4"> <Link href={`/posts/edit/${post.id}`} className="btn btn-warning"> <Pencil /> Edit </Link> <DeleteButton params={params} /> </div> <Views views={post.views} /> <Like likes={post.likes} /> </div> <p className="max-w-md">{post.content}</p> </div> ); }; export default DetailPage;
route.tsx
import prisma from "@/prisma/client"; import { NextRequest, NextResponse } from "next/server"; interface Props { params: { id: string; }; } export async function GET(req: NextRequest, { params }: Props) { try { const post = await prisma.post.update({ where: { id: params.id, }, data: { views: { increment: 1, }, }, select: { id: true, title: true, content: true, tag: true, views: true, likes: true, }, }); return NextResponse.json(post, { status: 200 }); } catch (error) { return NextResponse.json( { message: "Could not fecth the post" }, { status: 500 } ); } }
views.tsx
import { Eye } from "lucide-react"; interface Props { views: number; } const Views = ({ views }: Props) => { console.log("****Views****: ", views); return ( <div className="flex gap-1 items-center"> <Eye size={23} /> <span className="font-bold text-sm">{views}</span> </div> ); }; export default Views;
prisma.schema.ts
generator client { provider = "prisma-client-js" } datasource db { provider = "mongodb" url = env("DATABASE_URL") } model Tag { id String @id @default(cuid()) @map("_id") name String post Post[] } model Post { id String @id @default(cuid()) @map("_id") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String content String views Int @default(0) likes Int @default(0) tag Tag? @relation(fields: [tagId], references: [id]) tagId String }
问题分析与解决方案
可能的原因
- ID不匹配:请求传递的文章ID与数据库中存储的
_id(映射自模型的id)不一致,导致Prisma无法找到目标文档,update操作无实际效果且不会抛出错误(MongoDB特性)。 - 页面缓存:Next.js App Router默认会缓存服务器组件数据,即使
fetch设置了cache: "no-store",仍可能存在缓存导致旧数据重复展示。 - 未捕获的静默错误:可能存在权限、字段不存在等MongoDB层面的静默问题,未被当前代码捕获。
修复步骤
验证ID一致性
- 在
DetailPage中添加console.log(params.id),在route.tsx的GET方法中添加console.log(params.id),确认传递的ID与Prisma Studio中显示的文章_id完全一致。
- 在
增强错误处理与日志
修改route.tsx的GET方法,添加文档不存在判断与错误日志:export async function GET(req: NextRequest, { params }: Props) { try { const post = await prisma.post.update({ where: { id: params.id, }, data: { views: { increment: 1, }, }, select: { id: true, title: true, content: true, tag: true, views: true, likes: true, }, }); // 检查是否找到并更新了文章 if (!post) { return NextResponse.json({ message: "Post not found" }, { status: 404 }); } return NextResponse.json(post, { status: 200 }); } catch (error) { // 打印详细错误信息 console.error("Update error:", error); return NextResponse.json( { message: "Could not fetch the post", error: (error as Error).message }, { status: 500 } ); } }强制禁用页面缓存
在page.tsx顶部添加以下代码,确保服务器组件每次请求都重新渲染:export const revalidate = 0;验证数据库操作
- 使用Prisma Studio直接修改某篇文章的
views字段,确认数据库可以正常更新。 - 尝试通过Prisma CLI执行手动更新命令,验证操作有效性:
npx prisma studio # 或在脚本中执行 await prisma.post.update({ where: { id: "你的文章ID" }, data: { views: { increment: 1 } } })
- 使用Prisma Studio直接修改某篇文章的
检查Prisma版本
确保使用的Prisma版本支持MongoDB的increment操作,建议升级到最新稳定版:npm update prisma @prisma/client
内容的提问来源于stack exchange,提问作者Morteza
相关产品推荐
相关产品推荐

