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

NextJS构建后CRUD功能失效,数据更新无响应求助

问题原因

Next.js 默认在 npm run build 时执行静态生成(SSG),页面数据在构建阶段就被固化。dev 模式下页面会在每次请求时重新获取数据,CRUD 功能正常;但生产环境(或 build 后启动)中,静态页面不会主动刷新,导致删除/更新数据后页面内容无变化。

解决方案

根据数据更新频率选择合适的渲染策略,以下是具体实现:

1. 使用 SSR(服务端渲染)

适合需要实时同步数据的场景,每次用户访问页面时,服务器都会重新查询数据库并返回最新数据。

修改页面组件

import { PrismaClient } from '@prisma/client'

// 避免生产环境创建多个Prisma实例
const prisma = global.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') global.prisma = prisma

export default function PerfumeList({ perfumes }) {
  const handleDelete = async (perfumeId) => {
    // 调用后端API执行删除
    await fetch(`/api/perfumes/${perfumeId}`, { method: 'DELETE' })
    // 删除后刷新页面获取最新数据(简单实现,也可结合React状态管理局部更新)
    window.location.reload()
  }

  return (
    <div className="perfume-list">
      {perfumes.map(perfume => (
        <div key={perfume.id} className="perfume-item">
          <h3>{perfume.name}</h3>
          <button onClick={() => handleDelete(perfume.id)}>删除</button>
        </div>
      ))}
    </div>
  )
}

// 服务端获取数据
export async function getServerSideProps() {
  try {
    const perfumes = await prisma.perfume.findMany()
    // 将Prisma对象序列化为普通JSON(避免Next.js序列化报错)
    return { props: { perfumes: JSON.parse(JSON.stringify(perfumes)) } }
  } catch (err) {
    console.error('获取数据失败:', err)
    return { props: { perfumes: [] } }
  }
}

新增删除API路由

在 pages/api/perfumes/[id].js 创建API处理删除请求:

import { PrismaClient } from '@prisma/client'

const prisma = global.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') global.prisma = prisma

export default async function handler(req, res) {
  const { id } = req.query

  if (req.method !== 'DELETE') {
    return res.status(405).json({ message: '仅支持DELETE方法' })
  }

  try {
    await prisma.perfume.delete({ where: { id } })
    res.status(200).json({ message: '删除成功' })
  } catch (err) {
    res.status(500).json({ message: '删除失败', error: err.message })
  }
}

2. 使用 ISR(增量静态再生)

适合数据更新频率不高的场景,兼顾静态页面的性能和数据新鲜度。页面在构建时生成静态版本,之后每隔指定时间或按需重新生成。

仅需将上述 getServerSideProps 替换为 getStaticProps,并添加 revalidate 参数:

export async function getStaticProps() {
  const perfumes = await prisma.perfume.findMany()
  return {
    props: { perfumes: JSON.parse(JSON.stringify(perfumes)) },
    revalidate: 60 // 每60秒重新生成页面(可根据需求调整)
  }
}

3. 客户端局部更新(可选)

如果不想刷新页面,可在删除后通过客户端重新请求数据并更新组件状态:

import { useState, useEffect } from 'react'

export default function PerfumeList() {
  const [perfumes, setPerfumes] = useState([])

  // 初始加载数据
  useEffect(() => {
    fetchPerfumes()
  }, [])

  const fetchPerfumes = async () => {
    const res = await fetch('/api/perfumes')
    const data = await res.json()
    setPerfumes(data)
  }

  const handleDelete = async (perfumeId) => {
    await fetch(`/api/perfumes/${perfumeId}`, { method: 'DELETE' })
    // 删除后重新获取数据更新状态
    fetchPerfumes()
  }

  return (
    <div className="perfume-list">
      {perfumes.map(perfume => (
        <div key={perfume.id} className="perfume-item">
          <h3>{perfume.name}</h3>
          <button onClick={() => handleDelete(perfume.id)}>删除</button>
        </div>
      ))}
    </div>
  )
}

同时需要新增获取所有香水的API路由 pages/api/perfumes.js:

import { PrismaClient } from '@prisma/client'

const prisma = global.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') global.prisma = prisma

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      const perfumes = await prisma.perfume.findMany()
      res.status(200).json(perfumes)
    } catch (err) {
      res.status(500).json({ error: err.message })
    }
  } else {
    res.status(405).json({ message: '仅支持GET方法' })
  }
}
常见问题排查
  • 之前 getServerSideProps 失败,大概率是Prisma实例重复创建或数据序列化问题:生产环境需确保Prisma实例单例,且将查询结果转为普通JSON(JSON.parse(JSON.stringify(perfumes)))。
  • Vercel部署时需添加环境变量(如 DATABASE_URL),确保Prisma能连接到MongoDB。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:53:27