错误:如何从 getStaticProps 序列化数据:Next.js

问题描述 投票:0回答:14

我正在使用 Next.js,我尝试访问数据但收到此错误:

Error: Error serializing `.profileData` returned from `getStaticProps` in "/profile/[slug]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

我的代码:

import { getAllBusinessProfiles } from '../../lib/api';

const Profile = ({ allProfiles: { edges } }) => {
    return ( 
        <>
          <Head>
            <title>Profile</title>
          </Head>

          <Hero />

          <section>
            {edges.map(({ node }) => (
              <div key={node.id}>
                  <Link href={`/profile/${node.slug}`}>
                    <a> {node.businessInfo.name} </a>
                  </Link>
              </div>
            ))}
          </section>

        </>
     );
}
 
export default Profile;

export async function getStaticProps() {
    const allProfiles = await getAllBusinessProfiles();
    return {
      props: {
        allProfiles
      }
    };
  }

从 api.js 获取AllBusinessProfiles:

const API_URL = process.env.WP_API_URL;

async function fetchAPI(query, { variables } = {}) {
  const headers = { 'Content-Type': 'application/json' };

  const res = await fetch(API_URL, {
    method: 'POST',
    headers,
    body: JSON.stringify({ query, variables })
  });

  const json = await res.json();
  if (json.errors) {
    console.log(json.errors);
    console.log('error details', query, variables);
    throw new Error('Failed to fetch API');
  }
  return json.data;
}

export async function getAllBusinessProfiles() {
    const data = await fetchAPI(
      `
      query AllProfiles {
        businessProfiles(where: {orderby: {field: DATE, order: ASC}}) {
          edges {
            node {
              date
              title
              slug
              link
              uri
              businessInfo {
                name
                title
                company
                image {
                  mediaItemUrl
                  altText
                }
                highlight
                phone
                city
                country
                facebook
                instagram
                email
                website
                profiles {
                  profile
                  profileInfo
                }
                extendedProfile {
                  title
                  info
                }
              }
            }
          }
        }
      }
      
      `
    );
    return data?.businessProfiles;
};

这里可能出现什么错误?我在 Next.js 上使用了 getStaticProps 方法,但收到了上面的错误。请检查。谢谢。

错误: 服务器错误 错误:序列化从“/profile/[slug]”中的

.profileData
返回的
getStaticProps
时出错。 原因:
undefined
无法序列化为JSON。请使用
null
或省略此值。

我不知道是什么原因导致的。

javascript reactjs ecmascript-6 next.js server-side-rendering
14个回答
21
投票

调用返回对象的异步函数时添加

JSON.stringify

尝试像这样修改你的

getStaticProps
函数。

export async function getStaticProps() {
    const profiles = await getAllBusinessProfiles();
    const allProfiles = JSON.stringify(profiles)

    return {
        props: {
             allProfiles
        }
   };
}

JSON.stringify()
方法将 JavaScript 对象或值转换为 JSON 字符串,如果指定了替换函数,则可选择替换值;如果指定了替换数组,则可选择仅包含指定的属性。

来源:MDN


7
投票

我在使用 Mongoose 和 Next.js 时遇到了这个问题。

要解决这个问题:我从convert require切换到import,然后将结果包装在

JSON.parse(JSON.stringify(result));
中。

好:

import mongoose from 'mongoose'; 

不好:

const mongoose = require('mongoose');


3
投票

getStaticProps
中访问 Vercel 系统环境变量时,我遇到了相同的序列化错误。

使用

JSON.stringify
并没有达到目的,但
String()
有效。我的代码:

export async function getStaticProps() {
  const deploymentURL = String(process.env.NEXT_PUBLIC_VERCEL_URL);

  return {
    props: {
      deploymentURL,
    },
  };
}

感谢这个 GitHub 问题 的启发


3
投票

当我在 next js 中使用 redux 时,我遇到了同样的问题,原因是默认状态下的字段之一我将其设置为未定义。相反,我使用了

null

const INITIAL_STATE = {
  products: [],
  loading: false,
  error: undefined,
  cart: [],
};

error:undefined
导致了错误。因为“undefined”无法序列化:

export async function getStaticProps() {
    const allProfiles = await getAllBusinessProfiles();
    return {
      props: {
        allProfiles
      }
    };
  }

您正在返回“allProfiles”,这是异步的结果

getAllBusinessProfiles()
,它要么返回未定义、错误,要么返回对象的字段之一未定义。 “错误”对象在 javascript 中不可序列化


1
投票

您必须使用

undefined
作为变量的值,而不是使用
null

请注意,该错误准确地显示了哪个变量正在使用

undefined
作为其值。只需将其值修改为
null
即可。

值“未定义”表示变量已被声明,但尚未分配任何值。因此,变量的值是“未定义”。另一方面,“null”指的是不存在的对象,基本上意味着“空”或“无”。

来源:[1]


0
投票

试试这个,它对我有用:

export async function getStaticProps() {
  const APP_URL = process.env.PUBLIC_NEXT_WEB_APP_URL;
  const res = await fetch(`${APP_URL}/api/projects`);
  const projects = await res.json();
  return {
    props: {
      projects: projects?.data,
    },
  };
}

0
投票

我在尝试使用 id 在数据数组中查找匹配项时遇到了同样的问题。我遇到的问题是数组中的项目的 id 是数字,而我从 params 获取的值是字符串。所以我所做的就是将数字 id 转换为字符串以匹配比较。

export async function getStaticProps({ params }) {
  const coffeeStore = coffeeStoreData.find(
    (store) => store.id.toString() === params.slug[0]
  );
  return {
    props: {
      coffeeStore,
    },
  };
}


0
投票

安装名为 babel-plugin-superjson-nextsuperjson 的软件包,并添加包含以下内容的 .babelrc 文件:

{
  "presets": ["next/babel"],
  "plugins": ["superjson-next"]
}

请参阅此主题:https://github.com/vercel/next.js/discussions/11498


0
投票

我也遇到了类似的问题,我直接在 getStaticProps 内部通过 apollo 获取数据。要修复该错误,我所要做的就是将 spread 语法 添加到返回值中。

    return {
    props: {
      data: { ...data }
    }
  }

0
投票
return { props: { allProfiles: allProfiles || null } }

0
投票

getStaticProps()
函数中,获取数据后最初将为 json 格式,但您应该按如下方式更改它:

     const res = await fetch(`${APP_URL}/api/projects`);
     const data = JSON.parse(res);

现在就可以了。


0
投票

当你调用api时,你应该使用try catch。它将解决错误。

示例:

import axios from "axios";
    export const getStaticProps = async () => {
        try {
            const response = await axios.get("http:...");
            const data = response.data;
            return {
                props: {
                    posts: data
                }
            }
        } catch (error) {
            console.log(error);
        }
    }

希望对您有帮助!


0
投票

将 API 中的资源放入大括号中

const { res }  = await axios.post("http://localhost:3000/api", {data})
return { props: { res } }

0
投票

 const sanitizedProfile = Profiledata
    ? JSON.parse(JSON.stringify(Profiledata))
    : null;

© www.soinside.com 2019 - 2024. All rights reserved.