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

Next.js中getServerSideProps无法传递更新后Props的问题

问题1:getServerSideProps获取新数据但页面展示旧数据的原因及解决方法

核心原因

你的组件将initialEmails(来自props)作为useState的初始值,但useState的初始值仅在组件首次挂载时生效。当你通过<Link>导航回/notifications/emails时,Next.js会复用客户端已挂载的组件实例,此时新的props(initialEmails)已经更新,但组件的本地emails state不会自动同步,因此页面仍显示旧数据。

另外,虽然getServerSideProps已经拿到新数据,但组件没有监听props的变化来更新state,导致视图未刷新。

解决方案

方案1:监听props变化同步state

在组件中添加useEffect,监听initialEmails的变化,一旦props更新就同步到本地state:

const Notifications = ({ emails: initialEmails, error }: Props) => {
  const [emails, setEmails] = useState<Array<RecordEmail>>(initialEmails);

  // 监听props变化,同步到state
  useEffect(() => {
    setEmails(initialEmails);
  }, [initialEmails]); // 依赖项为initialEmails,当props更新时触发

  return (
    <div className="mt-4 flex flex-col space-y-2">
      <pre className="bg-gray-100 p-2 font-gtpressuratibold text-xs">
        <code>{JSON.stringify(emails, undefined, 2)}</code>
      </pre>
      <pre className="bg-gray-100 p-2 font-gtpressuratibold text-xs">
        <code>{JSON.stringify(initialEmails, undefined, 2)}</code>
      </pre>
    </div>
  )
}

方案2:直接使用props数据(无需本地state)

如果页面不需要对邮箱数据进行本地临时修改(比如编辑、删除),可以直接使用props中的initialEmails,去掉本地state,这样props更新时视图会自动刷新:

const Notifications = ({ emails: initialEmails, error }: Props) => {
  return (
    <div className="mt-4 flex flex-col space-y-2">
      <pre className="bg-gray-100 p-2 font-gtpressuratibold text-xs">
        <code>{JSON.stringify(initialEmails, undefined, 2)}</code>
      </pre>
    </div>
  )
}

额外注意:缓存控制

你的getServerSideProps中设置了Cache-Control: private, s-maxage=1, stale-while-revalidate=1,这个设置主要影响CDN或服务器端缓存。根据你的描述,getServerSideProps已经拿到新数据,所以这不是核心问题,但如果后续仍有缓存异常,可以尝试暂时去掉stale-while-revalidate测试。


问题2:导航到activate页面时index的getServerSideProps被调用的原因

这是Next.js的预取(Prefetch)机制导致的,属于设计行为:

  • <Link>组件默认开启prefetch={true},当浏览器处于空闲状态时,会自动预取链接指向的页面资源,包括执行目标页面的getServerSideProps。
  • 如果你的activate.tsx页面中存在返回/notifications/emails的<Link>,用户导航到activate页面后,Next.js会在后台预取index.tsx页面,从而触发其getServerSideProps。
  • 若刷新activate页面时也触发,可能是页面中存在其他触发index页面请求的逻辑,但最常见的原因还是预取机制。

如果想禁用预取,可以在<Link>组件上添加prefetch={false}:

<Link href="/notifications/emails" prefetch={false}>返回邮箱列表</Link>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:40:50