我正在尝试nextjs(来自react)。我认为我基本上让事情正常工作,但是当我创建一个服务器组件来测试服务器端的获取时,我得到了奇怪的结果。
大多数时候,当我启动服务器并加载页面时,
Loading...
消息始终显示。然后,如果我刷新页面,数据将按预期显示。浏览网站并返回页面通常会显示数据,但有时会显示Loading
,如果发生这种情况,我必须刷新页面才能再次显示数据。
我怀疑这与 nextjs 缓存有关,但我不确定。
我的页面组件看起来像这样,大致是从nextjs文档中窃取的:
let statsData: StatsType[];
let url = 'stats';
async function getData() {
const res = await fetchDataServerSide(url);
if (!res.ok) {
throw new Error('Failed to fetch data')
}
await res.json().then(json => {
statsData = json;
})
}
const Dashboard = () => {
const data = getData();
/*if (error) return <div>Failed to load</div>*/
if (!statsData) {
return <div>Loading...</div>
} else {
return (
<div className={"p-6"}>
<div className={"pb-6"}>
<Stats stats={statsData}/>
</div>
</div>
)
}
}
export default Dashboard
我的
fetchDataServerSide
只是尝试从我需要提取数据的每个页面中抽象 fetch
,因为我每次都需要传入标头才能使用我的 laravel API 后端:
async function fetchDataServerSide(url: string): Promise<Response> {
'use server'
let fetch_path = process.env.NEXT_PUBLIC_BACKEND_URL + '/api/' + url
const options: RequestInit = {
method: "GET",
headers: {
"Accept": "application/json",
"Referer": process.env.APP_URL,
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json",
"cookie": "XSRF-TOKEN=" + cookies().get('XSRF-TOKEN').value + ";laravel_session=" + cookies().get('laravel_session').value,
}
}
return await fetch(fetch_path, options);
}
对我做错了什么有什么想法吗?
您不是在等待数据被获取。您需要将“仪表板”更改为异步组件,并使用带有后备加载 UI 的悬念边界。它将显示正在加载的 UI,直到加载了子级所需的数据。加载数据后,Stats 组件将呈现数据。 wait 组件用于等待数据被获取,获取后将数据返回给子组件。
import { notFound } from "next/navigation";
import { Suspense } from 'react';
async function Await<T>({ promise, children }: { promise: Promise<T>, children: (value: T) => JSX.Element }) {
let data = await promise;
if (!data) return notFound();
return children(data);
}
const Dashboard = async () => {
const data = getData();
return (
<Suspense fallback={<div>Loading...</div>}>
<Await promise={data}>
{( data ) => <Stats stats={data}/>}
</Await>
</Suspense>
);
};