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

Next.js Beta版Mutation问题:router.refresh()未刷新服务端数据

问题分析与解决

你的问题出在两个核心点上:

1. 服务端数据被缓存,router.refresh()未触发真实请求

Next.js 中 fetch 默认对 GET 请求启用缓存机制,你的getCategories函数调用第三方 API 时未指定缓存策略,导致每次调用都会复用缓存数据,所以router.refresh()后服务端并没有重新请求新数据,id自然不会更新。

2. 客户端组件本地状态未同步服务端新props

你的Test组件用useState初始化了本地状态todo,但useState的初始值仅在组件首次挂载时生效。当服务端组件重新渲染并传递新的id给Test时,本地状态不会自动更新,所以你看到的还是之前客户端设置的id。


解决方案

步骤1:修改服务端fetch的缓存策略

在getCategories的fetch请求中添加cache: 'no-store',强制每次请求都从服务器获取新数据:

export async function getCategories() {
  try {
    const res = await fetch("https://random-data-api.com/api/v2/banks?size=1", {
      cache: 'no-store' // 禁用缓存,每次请求都获取新数据
    });
    if (res.status === 200) { // 直接使用状态码200,避免未定义的ResponseStatusCode报错
      const data = await res.json();
      return data;
    }
  } catch (error) {
    console.log(error);
  }
}

步骤2:让客户端组件同步服务端props的变化

在Test组件中添加useEffect,监听props.id的变化,更新本地状态todo:

"use client";

import { useRouter } from "next/navigation";
import { useState, useTransition, useEffect } from "react";

interface Todo {
  id: number;
}

export const Test = (props: Todo) => {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [isFetching, setIsFetching] = useState(false);
  const [todo, setTodo] = useState<any>(props.id);

  // 监听props.id变化,同步更新本地状态
  useEffect(() => {
    setTodo(props.id);
  }, [props.id]);

  const isMutating = isFetching || isPending;

  async function handleChange() {
    setIsFetching(true);
    const response = await fetch(
      `https://random-data-api.com/api/v2/users?size=1`,
      {
        method: "GET",
      }
    );

    setIsFetching(false);
    const data = await response.json();
    setTodo(data.id);

    startTransition(() => {
      router.refresh();
    });
  }

  return <button onClick={handleChange}>{todo}</button>;
};

修改后流程:

  1. 点击按钮后客户端先更新本地状态显示临时id
  2. router.refresh()触发服务端组件重新渲染,getCategories重新请求API获取新的服务端id
  3. 服务端将新id传给Test组件,useEffect监听到props变化,同步更新本地状态为服务端的新id

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:43:13