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

Next.js中禁用React Query路由切换时自动重新获取数据

解决Next.js 13 + React Query 路由返回时自动重获数据的问题

核心问题分析

你遇到的自动重获问题,主要源于两个关键点:

  • 若使用Next.js 13的App Router,Giveaway组件未标记为客户端组件,导致每次路由返回时Server Component重新渲染,重复执行查询(此时React Query的客户端缓存配置完全不生效)。
  • 缺少部分禁用自动重获的关键配置,即使组件是客户端类型,仍可能触发不必要的重获。

解决方案步骤

1. 将使用useQuery的组件转为客户端组件

在Giveaway.tsx最顶部添加'use client'指令——React Query的钩子只能在客户端组件中运行,这是Next.js 13 App Router的强制要求:

'use client'; // 必须添加这行

import { useGiveawayDetails } from './path-to-your-query-file';
// 其他导入代码...

const Giveaway = () => {
    const { isLoading, isError, data, error, refetch } = useGiveawayDetails(); // 解构refetch用于手动触发
    // 组件原有内容...
}

export default Giveaway

2. 完善查询配置,彻底禁用自动重获

修改useGiveawayDetails的配置,补充禁用网络重连时的自动重获,并根据需求调整数据新鲜度和定时重获规则:

export const useGiveawayDetails = () => useQuery(["giveawayDetails"], async () => {
    const response = await axios.get("/api/giveaway/giveaway-details")
    const data: giveawayDetails = await response.data;
    console.log(data);
    return data;
},
    {
        refetchOnWindowFocus: false,
        refetchOnMount: false,
        refetchOnReconnect: false, // 新增:禁止网络重连时自动重获
        staleTime: Infinity, // 可选:设置数据永远不过期,避免因数据过期触发隐式重获
        refetchInterval: false, // 若不需要定时重获,将原5分钟设置改为false
        onError: (error: any) => {
            if (error.response.status === 422 || error.response.status === 401) {
                toast(error.response.data.data.detail, { type: "error", toastId: "unauthorized" });
            } else {
                toast(error.response.data.data.detail, { type: "error" });
            }
        }
    },
);

3. 实现手动触发查询

从useQuery中解构出refetch函数,在需要的场景(比如按钮点击)调用它:

const Giveaway = () => {
    const { isLoading, isError, data, error, refetch } = useGiveawayDetails();

    const handleManualRefetch = async () => {
        await refetch();
        // 可选:添加重获成功提示
        toast("数据已刷新", { type: "success" });
    };

    return (
        <div className={styles.container}>
            <p className="text-600 text-md">Giveaways</p>
            {/* 添加手动刷新按钮 */}
            <button onClick={handleManualRefetch} disabled={isLoading}>
                {isLoading ? "刷新中..." : "手动刷新"}
            </button>
            {/* 原有渲染内容... */}
        </div>
    )
}

关键补充说明

  • 若使用Next.js的Pages Router,无需添加'use client',但仍需确保上述查询配置的完整性。
  • staleTime: Infinity会让React Query认为数据永远新鲜,若需要数据在一段时间后变旧但仍不自动重获,可设置具体时长(如24 * 60 * 60 * 1000表示1天)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:22:40