在nextjs中获取服务器端数据

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

我正在尝试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);
}

对我做错了什么有什么想法吗?

reactjs laravel next.js fetch-api
1个回答
0
投票

您不是在等待数据被获取。您需要将“仪表板”更改为异步组件,并使用带有后备加载 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>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.