NextJS中Fetch数据不更新:重启服务器/刷新页面无效
NextJS页面API数据不更新问题解决方案
我正在开发一个NextJS程序,需要每5分钟从API获取数据并在页面展示。但今早测试后,数据一直停留在当时的状态,即使重启服务器或刷新页面,数据仍未更新。
页面代码
import React from 'react'; export default async function Page() { const res = await fetch('MY API'); const data = await res.json(); // 提取特定数据 const instrumentID = data[0]?.instrumentID || ''; const location = data[0]?.location || ''; const utc = data[0]?.utc || ''; const timestamp = data[0]?.timestamp || ''; const weight = data[0]?.data.filter(item => item.unit === 'Tons') || []; const temperature = data[0]?.data.find(item => item.name === 'Temperature') || {}; const humidity = data[0]?.data.find(item => item.name === 'Humidity') || {}; const windSpeed = data[0]?.data.find(item => item.name === 'Wind Speed') || {}; const windDirection = data[0]?.data.find(item => item.name === 'Wind Direction') || {}; return ( <div className="col"> <div>Instrument ID: {instrumentID}</div> <div>Location: {location}</div> <div>Hora: {utc}</div> <div>Timestamp: {timestamp}</div> <div> <h2>Weight:</h2> {weight.map(item => ( <div key={item.name}> <div>{item.name}: {item.value} {item.unit}</div> </div> ))} </div> <div> <h2>Temperature:</h2> <div>{temperature.name}: {temperature.value} {temperature.unit}</div> </div> <div> <h2>Humidity:</h2> <div>{humidity.name}: {humidity.value} {humidity.unit}</div> </div> <div> <h2>Wind:</h2> <div>{windSpeed.name}: {windSpeed.value} {windSpeed.unit}</div> <div>{windDirection.name}: {windDirection.value} {windDirection.unit}</div> </div> </div> ); }
Postman获取的数据结构
[ { "utc": "2024-01-07T21:00:00.000+00:00", "timestamp": "2024-01-07T18:00:00.000+00:00", "instrumentID": "XXX", "location": "Space", "gpsCoordinates": "123,911", "data": [ { "unit": "Tons", "name": "Weight", "value": "5.9" }, { "unit": "Celsius", "name": "Temperature", "value": "21.4" }, { "unit": "% RH", "name": "Humidity", "value": "87.6" }, { "unit": "mtr/sec", "name": "Wind Speed", "value": "0.5" }, { "unit": "degrees", "name": "Wind Direction", "value": "25.0" } ] } ]
问题原因及解决方法
1. Next.js静态渲染缓存导致数据不更新
Next.js 13+ App Router中,异步页面组件默认会被静态优化,fetch请求的结果会被缓存并复用,即使重启服务器或刷新页面也不会重新发起请求。
解决方法:
- 给fetch添加
cache: 'no-store'选项,强制每次请求都获取最新数据:const res = await fetch('MY API', { cache: 'no-store' }); - 或者在页面组件上方设置
revalidate属性,指定页面重新验证的时间(300秒即5分钟):export const revalidate = 300; // 每5分钟重新验证数据 export default async function Page() { // 现有代码 }
2. 缺少前端定时刷新逻辑
当前代码仅在页面初始化时请求一次数据,没有实现每5分钟自动刷新的功能。若需要前端主动定时拉取最新数据,需将组件改为客户端组件,使用useEffect和setInterval实现定时任务。
修改后的客户端组件代码:
'use client'; import React, { useState, useEffect } from 'react'; export default function Page() { const [data, setData] = useState(null); const fetchData = async () => { const res = await fetch('MY API', { cache: 'no-store' }); const fetchedData = await res.json(); setData(fetchedData); }; // 初始化加载+定时刷新 useEffect(() => { fetchData(); const interval = setInterval(fetchData, 5 * 60 * 1000); // 组件卸载时清理定时器 return () => clearInterval(interval); }, []); if (!data) return <div>加载中...</div>; // 数据提取逻辑与原代码一致 const instrumentID = data[0]?.instrumentID || ''; const location = data[0]?.location || ''; const utc = data[0]?.utc || ''; const timestamp = data[0]?.timestamp || ''; const weight = data[0]?.data.filter(item => item.unit === 'Tons') || []; const temperature = data[0]?.data.find(item => item.name === 'Temperature') || {}; const humidity = data[0]?.data.find(item => item.name === 'Humidity') || {}; const windSpeed = data[0]?.data.find(item => item.name === 'Wind Speed') || {}; const windDirection = data[0]?.data.find(item => item.name === 'Wind Direction') || {}; return ( <div className="col"> <div>Instrument ID: {instrumentID}</div> <div>Location: {location}</div> <div>Hora: {utc}</div> <div>Timestamp: {timestamp}</div> <div> <h2>Weight:</h2> {weight.map(item => ( <div key={item.name}> <div>{item.name}: {item.value} {item.unit}</div> </div> ))} </div> <div> <h2>Temperature:</h2> <div>{temperature.name}: {temperature.value} {temperature.unit}</div> </div> <div> <h2>Humidity:</h2> <div>{humidity.name}: {humidity.value} {humidity.unit}</div> </div> <div> <h2>Wind:</h2> <div>{windSpeed.name}: {windSpeed.value} {windSpeed.unit}</div> <div>{windDirection.name}: {windDirection.value} {windDirection.unit}</div> </div> </div> ); }
3. API响应缓存问题
如果API服务器返回的响应带有强缓存头(如Cache-Control: max-age=xxx),浏览器或CDN会缓存数据,导致新请求无法获取最新内容。此时可在fetch中添加请求头禁用缓存:
const res = await fetch('MY API', { headers: { 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Expires': '0' } });
内容的提问来源于stack exchange,提问作者StackScripter
相关产品推荐
相关产品推荐

