You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14中如何避免SWR首次渲染时数据为undefined?

在Next.js 14中实现首屏渲染时获取数据(替代getServerSideProps)

你的核心需求是在首屏渲染时就拿到数据,避免undefined,对应旧版本的getServerSideProps效果。在Next.js 14的App Router中,最直接的方案是利用Server Component预取数据,再传递给需要交互的Client Component,下面是具体实现:

方案1:Server Component预取数据,传递给Client Component

因为你的Home组件用到了useState处理弹窗状态,必须标记为"use client",所以我们将数据获取逻辑放在默认的Server Component(app/page.js)中,再把数据作为props传给Home组件。

步骤1:修改app/page.js(Server Component)

// app/page.js - 默认是Server Component,无需额外标记
import Home from "./Home";

export default async function Page() {
  // 服务端发起请求,首屏渲染时直接完成数据获取
  const res = await fetch("/api/get", { 
    cache: "no-store" // 每次请求都获取最新数据,等价于getServerSideProps的动态效果
  });
  
  if (!res.ok) {
    throw new Error("获取任务列表失败");
  }
  
  const initialData = await res.json();
  return <Home initialData={initialData} />;
}

步骤2:修改Home组件(Client Component)

接收Server Component传来的初始数据,传递给SWR作为 fallback 值:

"use client";
import { useState } from "react";
import ListTasks from "@/components/ListTasks/ListTasks";
import Modal from "@/components/Modal/Modal";
import useGetData from "@/hooks/useGetData";

export default function Home({ initialData }) {
  const [modalProps, setModalProps] = useState({
    isOpen: false,
    type: "",
  });
  
  // 传入服务端预取的初始数据,首渲染时data不会是undefined
  const data = useGetData(initialData);

  return (
    <div className="bg-slate-500 w-screen h-screen flex justify-center items-center">
      {modalProps.isOpen && (
        <Modal modalProps={modalProps} setModalProps={setModalProps} />
      )}
      <div className="bg-gray-400 w-1/3 h-3/4 rounded">
        <p className="text-white text-center text-2xl font-bold">To-do App</p>
        <div className="w-10 h-10 bg-black rounded flex justify-center items-center cursor-pointer">
          <p
            className="text-white text-6xl pb-2"
            onClick={() =>
              setModalProps({ ...modalProps, isOpen: true, type: "post" })
            }
          >
            +
          </p>
        </div>
        <div className="bg-red-300 indent-5 rounded m-3 py-1">
          <ListTasks 
            modalProps={modalProps} 
            setModalProps={setModalProps} 
            tasks={data}
          />
        </div>
      </div>
    </div>
  );
}

步骤3:修改useGetData钩子

支持接收初始数据作为SWR的 fallback 值:

import useSWR from "swr";

export default function useGetData(initialData) {
  const fetcher = (...args) => fetch(...args).then((res) => res.json());
  
  const { data } = useSWR("/api/get", fetcher, {
    fallbackData: initialData, // 首渲染直接用服务端传来的数据
  });

  return data;
}

额外说明

  • 如果你的数据是静态的(不需要每次请求更新),可以去掉{ cache: "no-store" },Next.js会自动缓存数据,实现类似getStaticProps的效果。
  • 服务端fetch不会有跨域问题,因为请求是在服务器内部发起的。
  • SWR会在客户端后台自动重新验证数据,保证数据新鲜度。

内容的提问来源于stack exchange,提问作者Ozan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:38:26