如何解决在Next.js中序列化日期对象JSON的错误

380 阅读2分钟

如果你使用过Next.js和数据库,你肯定遇到过这样的问题。

你在getServerSideProps()getStaticProps() 中获取一些数据,例如像这样用Prisma:

export async function getServerSideProps() {
  let cars = await prisma.car.findMany()

  return {
    props: {
      cars,
    },
  }
}

现在,如果数据库表有一个包含日期的字段,在JavaScript中被转换为一个Date 对象,你会得到这样的错误。

这是因为你必须返回一个JSON可序列化的对象。一个Date 对象不能被本机转换为JSON。

在这种情况下,解决方案可以像这样简单:

export async function getServerSideProps() {
  let cars = await prisma.car.findMany()

  cars = JSON.parse(JSON.stringify(cars))

  return {
    props: {
      cars,
    },
  }
}

这样做的效果是将Date 对象转换为一个字符串。

我喜欢这个解决方案,因为它是明显的,可见的,而且不具干扰性。

另一个解决方案是使用一个叫做superjson 的库和它的Next.js适配器next-superjson

npm install next-superjson superjson

并将其添加到next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
}

const { withSuperjson } = require('next-superjson')

module.exports = withSuperjson()(nextConfig)

我是在James Perkins的博文《在Next数据获取中处理日期对象》中发现的。

例如,如果你试图返回一个复杂的对象,如Fetch响应,会发生类似的错误。

export async function getServerSideProps() {
  const res = await fetch(...)

  return {
    props: {
      res
    },
  }
}

但在这种情况下,修复并不那么容易。

你需要首先获得响应文本,如

export async function getServerSideProps() {
  const res = await fetch(...)
  const data = await res.json() 

  return {
    props: {
      data
    },
  }
}

还有一件事!⚠️ ✋

在一月底,我将组织网络开发训练营

这是一个为期10周的同学会在线课程,我将指导你成为一名Web开发人员。

这不仅仅是 "一个课程"。它是我每年组织一次的大型活动。

我们将从零开始,学习网络开发的基础知识,HTML,CSS,JavaScript,Tailwind,Node.js,然后我们将学习React,JSX,如何使用PostgreSQL,Astro,Next.js,Prisma等等

在前10周结束时,你将知道如何创建网站和网络应用程序,我将为你解锁Bootcamp的第二阶段:你将获得Bootcamp毕业生专属的大量项目,所以你可以按照我的指示建立像带有认证的私人区域,克隆Twitter YouTube Reddit等流行网站,创建电子商务网站,等等。

因为一旦你掌握了基础知识,你只能通过在真正的、令人兴奋的项目上工作来学习。