提问人:victor 提问时间:5/17/2023 最后编辑:Youssouf Oumarvictor 更新时间:8/31/2023 访问量:7639
如何在最新的 Next.js 中获取服务器端数据?尝试了 getStaticProps,但它没有运行并且未定义
How to fetch data server-side in the latest Next.js? Tried getStaticProps but it's not running and getting undefined
问:
我正在使用 Next.js 开发 Django Rest 框架,并且我无法从 API 获取数据。我在这个 url 中有数据,当我访问该 url 时,我会看到数据。http://127.0.0.1:8000/api/campaigns
问题是当我使用 Next.js 获取和控制台数据时,我得到 .此外,当我尝试映射数据时,出现错误:undefined
未处理的运行时错误
错误:无法读取未定义的属性(读取“map”)
这是我完成数据获取的文件:Index.js
import React from 'react'
export default function Index ({data}) {
console.log(data)
return (
<div>
<main>
<h1>Available Campaigns</h1>
{data.map((element) => <div key={element.slug}>
<div>
<div>
<img src={element.logo} height={120} width={100} alt="image" />
</div>
<div></div>
</div>
</div>)}
</main>
</div>
);
}
export async function getStaticProps() {
const response = await fetch("http://127.0.0.1:8000/api/campaigns");
const data = await response.json();
return {
props: {
data: data
},
}
}
这是我访问URL时获得的数据的屏幕截图:
下面是前端内 Next.js 应用的文件结构:
另外,请注意,我使用的是最新版本的Next.js。任何帮助将不胜感激。谢谢。
答:
像 getServerSideProps
和 getStaticProps
这样的方法用于在服务器上获取数据,但它们仅适用于 pages
文件夹中的页面组件(在 Next.js 中设置路由的初始方法)。
从 Next.js 13 开始,在应用程序
目录中(当您对下图中显示的最后一个问题回答“是”时使用)中,我们有服务器组件,您可以在其中直接在组件主体中获取数据,如以下代码片段所示(请阅读注释):
/*
If you want to access headers or cookies while fetching data,
you can use these functions:
*/
import { cookies, headers } from "next/headers";
/*
If the below component is the default export of a `page.js` and you are using
dynamic routes, slugs will be passed as part of `params`, and
query strings are passed as part of `searchParams`.
*/
export default async function Component({ params, searchParams }) {
/*
This request should be cached until manually invalidated.
Similar to `getStaticProps`.
`force-cache` is the default and can be omitted.
*/
const staticData = await fetch(`https://...`, { cache: "force-cache" });
/*
This request should be refetched on every request.
Similar to `getServerSideProps`.
*/
const dynamicData = await fetch(`https://...`, { cache: "no-store" });
/*
This request should be cached with a lifetime of 10 seconds.
Similar to `getStaticProps` with the `revalidate` option.
*/
const revalidatedData = await fetch(`https://...`, {
next: { revalidate: 10 },
});
return "...";
}
话虽如此,您可以在不使用任何库的情况下获取数据,甚至可以使用 ORM 直接与数据库通信,在这种情况下,您可以使用路由段配置:fetch()
// layout.js OR page.js OR route.js 👈🏽
import prisma from "./lib/prisma";
/*
Keep one of the possibilities shown below (there are more on the doc),
depending on your needs.
*/
export const revalidate = 10; // If you want to revalidate every 10s
// OR
export const dynamic = "force-dynamic"; // If you want no caching at all
// ...
async function getPosts() {
const posts = await prisma.post.findMany();
return posts;
}
export default async function Page() {
const posts = await getPosts();
// ...
}
评论
在应用程序目录中,您不能使用 、 等方法获取数据。与服务器组件相反,您可以使组件自异步并直接在组件主体中获取数据。此外,您可以将数据传递给客户端组件以提供服务。getServerSideProps
getStaticProps
getInitialProps
export async function getData(){
const res = await fetchData();
const data = res.json()
return data
}
现在,您可以在主组件中调用此异步函数
export async function(){
const data = await getData()
return (<ClientComponent data />)
}
评论
此 StackOverFlow 问题(无法在 Next.js 13 中使用 GetStaticProp)已作为此问题的重复项关闭。
为了帮助像我这样的新手:
您不能在 Nextjs 13 中使用 getStaticProps(使用 App Router)。
新的方法是只使用 fetch。您可以在此处阅读有关 fetch 的更多信息。
async function getArtist(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}`)
return res.json()
}
这张图片比较了新旧做事方式。图片来源
由于新的默认值是缓存所有 fetch 请求(除非它们选择退出),因此在静态组件中调用 fetch 具有与 相同的效果。您可以在此处阅读有关静态数据获取的更多信息。getStaticProps
因此,要明确这个正常的获取请求:
//Similar to 'getStaticProps' when used in a static rendering component
fetch(API_URL)
与此“force-cache”请求相同:
//This request would be cached until manually invalidated.
//Similar to 'getStaticProps'
//Use this type of fetching for data that does not change often.
fetch(API_URL, { cache: 'force-cache' })
你为什么一开始就想使用 getStaticProps?
为了帮助那些在教程中找到并在这里找到方法的新手,您想要使用的原因是您希望渲染一次页面,然后将该页面发送给每个用户。getStaticProps
getStaticProps
这使您的页面更快,向用户发送更少的代码,并且更适合 SEO 等。
但是,如果您需要获取一些数据来呈现该页面一次,该怎么办?在 Nextjs 13 之前,您将使用 .getStaticProps
现在你在一个静态组件中。效果是一样的。fetch
这种效果是,一旦(在部署项目的构建时)Nextjs 将获取一些数据,然后使用该数据来渲染页面,然后将预渲染的页面发送给需要它的每个人。
如果需要使用动态路由静态生成一堆页面,则该函数可用于在构建时生成路由,而不是在请求时按需生成动态路由。信息在这里。generateStaticParams
对于新手来说,如果你不知道什么是动态路由,就用.:)fetch
评论
const data = await response.json(); console.log(data)
console.log(data)