React+Next.js条件渲染异常:页面过期后刷新仍展示原页面
问题分析与解决方案
你的问题核心是缺少过期状态的判断逻辑,且未在服务端/客户端正确校验过期时间,导致页面过期后仍展示原内容。以下是具体修复步骤:
1. 补充过期判断逻辑(服务端+客户端)
假设黑五页面数据page中包含expiryDate过期日期字段,我们需要在服务端先计算过期状态,同时在客户端做二次校验(避免静态缓存延迟)。
修改getStaticProps
export async function getStaticProps({ preview = false, params, previewData }) { const page = await ContentfulApi.getBlackFridayPromoBySlug(params.slug, { preview, enviroment: previewData?.enviroment }); const expiredPage = await ContentfulApi.getPageContentBySlug( "expired-page", { preview, enviroment: previewData?.enviroment } ); const globalSettings = await ContentfulApi.getGlobalSettings({ preview }); // 计算是否过期:转换日期格式并对比当前时间 const expiryDate = new Date(page.expiryDate); const currentTime = new Date(); // 注意时区一致性,确保Contentful返回的日期为标准格式(如ISO) const isExpired = currentTime > expiryDate; return { props: { page, expiredPage, globalSettings, isExpired, // 将过期状态传给组件 expiryDate: expiryDate.toISOString() // 传递标准格式日期给客户端校验 }, revalidate: 60 // 缩短重验证周期,加快过期页面更新 }; }
修改组件逻辑
function BlackFridayPages({ page, expiredPage, globalSettings, isExpired, expiryDate }) { // 客户端二次校验,避免静态缓存未及时更新 const [clientExpired, setClientExpired] = React.useState(isExpired); React.useEffect(() => { const currentTime = new Date(); const expiry = new Date(expiryDate); setClientExpired(currentTime > expiry); // 未过期时设置定时器,到点自动切换过期页面 if (!clientExpired) { const timeUntilExpiry = expiry.getTime() - currentTime.getTime(); const timer = setTimeout(() => setClientExpired(true), timeUntilExpiry); return () => clearTimeout(timer); } }, [expiryDate, clientExpired]); if (clientExpired) { return <ExpiredPage expiredPage={expiredPage} />; } return <BlackFridayPage page={page} />; // 记得将page数据传入页面组件 }
2. 核心问题说明
- 原组件中
!expired变量未定义,完全没有过期判断逻辑,因此永远不会触发过期页面 revalidate:100意味着页面最多100秒才会重新生成,缩短周期能让过期状态更快生效- 客户端校验+定时器的组合,能确保即使静态缓存未更新,用户也能在过期时间点立刻看到过期页面
3. 额外注意事项
- 确认Contentful中存储的过期日期为标准格式(如ISO字符串),避免时区偏差
- 如果过期日期存在于
globalSettings而非单个页面数据中,直接替换为globalSettings.blackFridayExpiryDate即可
内容的提问来源于stack exchange,提问作者journalsup
相关产品推荐
相关产品推荐

