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

NextJS生产环境ISR页面刷新状态不更新、内容闪烁如何修复?

问题根因

你遇到的闪烁本质是两个数据源不同步导致的:

  • getStaticProps搭配revalidate:1属于NextJS的增量静态再生(ISR)逻辑,这个配置的规则是:用户请求时先直接返回已经缓存的静态页面,后台才会静默触发重新渲染生成新页面,下一次用户访问才会返回更新后的内容,所以首次拿到的页面大概率是旧缓存数据
  • 客户端挂载后又触发了一次API拉取,拿到最新数据后替换了页面上的旧值,就出现了跳变闪烁
修复方案

方案1:删除客户端重复拉取逻辑(最推荐,性能最好)

直接用getStaticProps传递下来的props作为唯一数据源,不要在客户端重复调用API,从根源上消除两个数据源的差异,就不会有闪烁。
代码修改示例:

// 页面组件直接接收props里的data,删掉useEffect里的fetchNewData和loading判断逻辑
export default function Page({ data, error }) {
  if (error) return "Error!";
  // 直接用服务端返回的data渲染,不需要额外拉取
  return <div>{data.content}</div>
}

export async function getStaticProps() {
  try {
    const response = await fetch(`link`);
    const data = await response.json();
    return {
      props: {
        data: data,
        error: null
      },
      revalidate: 1,
    };
  } catch (e) {
    return {
      props: {
        data: null,
        error: "请求失败"
      },
      revalidate: 1,
    }
  }
}

方案2:切换为服务端渲染(SSR),保证每次返回最新数据

如果你的业务对数据实时性要求极高,不能接受ISR的缓存延迟,直接把getStaticProps换成getServerSideProps,每次用户请求都会实时拉取最新数据返回,不会有旧缓存问题,也不需要客户端额外拉取:
代码示例:

export async function getServerSideProps() {
  try {
    const response = await fetch(`link`);
    const data = await response.json();
    return {
      props: {
        data: data,
        error: null
      }
    };
  } catch (e) {
    return {
      props: {
        data: null,
        error: "请求失败"
      }
    }
  }
}

方案3:保留客户端拉取,做平滑更新无感知替换

如果你确实需要客户端主动拉取最新数据,可以去掉首次渲染的loading判断,默认先展示服务端返回的旧数据,客户端拉到新数据后静默替换,还可以加过渡动画弱化变化感知:
代码示例:

import { useState, useEffect } from 'react'

export default function Page({ data: serverData }) {
  const [data, setData] = useState(serverData)
  const [error, setError] = useState(null)

  useEffect(() => {
    const fetchNewData = async () => {
      try {
        const res = await fetch('your-api-link')
        const newData = await res.json()
        // 只有数据真的变化了才更新,避免无意义重渲染
        if (JSON.stringify(newData) !== JSON.stringify(serverData)) {
          setData(newData)
        }
      } catch (e) {
        setError(e.message)
      }
    }
    fetchNewData()
  }, [])

  if (error) return "Error!";
  // 全程不展示loading,直接渲染当前数据,变化时可以加CSS过渡
  return <div className="transition-all duration-300">{data.content}</div>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:36:01