簡體   English   中英

原因:`object`([object Date]")無法序列化為JSON,請只返回JSON可序列化數據類型

[英]Reason: `object` ("[object Date]") cannot be serialized as JSON. Please only return JSON serializable data types

我正在使用 prisma 和 Next.js。當我嘗試在getStaticProps中從 prisma 檢索內容時,它確實獲取了數據,但我無法將其傳遞給主要組件。

export const getStaticProps = async () => {
  const prisma = new PrismaClient();
  const newsLetters = await prisma.newsLetters.findMany();
  console.log(newsLetters);

  return {
    props: {
      newsLetters: newsLetters,
    },
  };
};

正如您在此圖像中看到的,它正在獲取和打印內容。

在此處輸入圖像描述

但是當我通過時,將其作為道具傳遞時出現以下錯誤

Reason: `object` ("[object Date]") cannot be serialized as JSON. Please only return JSON serializable data types.

看起來 nextJS 出於性能原因不喜歡序列化除標量類型之外的任何東西。 您可以在此github 問題中閱讀更多內容。 處理此問題的最佳方法是將 Date 對象轉換為 UNIX 時間戳,然后再返回它們。

// your data
let newsLetters = [
    {
        id: 'your-id',
        email: 'email@example.com',
        createdAt: new Date()
    }
];

// map the array
newsLetters.map(x => {
    x.createdAt = Math.floor(x.createdAt / 1000);
    return x;
})

// use newsLetters now
console.log(newsLetters);

根據 NextJS API Docs getStaticProps 返回“應該是可序列化的 object 以便通過的任何道具,都可以使用 JSON.stringify 進行序列化。”

在他們允許的引擎蓋下,boolean、數字、字符串以及任何通過 Lodash isPlainObject 測試的東西。 https://lodash.com/docs/#isPlainObjectChecks In Lodash Documentation for this function it claims "Checks if value is a plain object, that is, an object created by the Object constructor or one with a [[Prototype]] of null."

以下堆棧帖子討論了差異。 JavaScript中的object和普通object的區別?

基於@Viktor Kynchev 的回答,根據您對道具的需求,您可以將其轉換為字符串、數字或 Lodash 的 isPlainObject 接受的其他類型。

對我來說,我有一個日期 Object 通過 Prisma API 提供,就像 OP 一樣,我只是將它轉換為這樣的字符串。

for (const element of newsLetters) {
  element.createdAt = element.createdAt.toString()
}

如果您使用的是typescript ,則不能將createdAt的類型更改為字符串或數字,如下所示:

newsLetter.createdAt = newsLetter.createdAt.toString();
// Error: Type 'string' is not assignable to type 'Date'.

相反,您可以在 JSON.parse 中使用 JOSN.stringfy 來創建可序列化的 object:

export const getStaticProps = async () => {
  const prisma = new PrismaClient();
  const newsLetters = await prisma.newsLetters.findMany();

  return {
     props: {
        newsLetters: JSON.parse(JSON.stringify(newsLetters)) // <===
     }
  }
}

您可以使用Blitz 的superjson package來完成這項工作。 他們在https://github.com/blitz-js/superjson#using-with-nextjs上有說明:

與 Next.js 一起使用

Next.js 提供的getServerSidePropsgetInitialPropsgetStaticProps數據掛鈎不允許您傳輸 Javascript 對象,例如 Dates。 除非您將日期轉換為字符串等,否則它將出錯。

值得慶幸的是,Superjson 是繞過該限制的完美工具!

Next.js SWC插件(實驗性,v12.2或以上)

Next.js SWC 插件是實驗性的,但 promise 有顯着的加速。 要使用SuperJSON SWC 插件,請安裝它並將其添加到您的next.config.js

 yarn add next-superjson-plugin
 // next.config.js module.exports = { experimental: { swcPlugins: [ [ 'next-superjson-plugin', { excluded: [], }, ], ], }, }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM