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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:23:15