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

在NextJS+TypeScript中使用ReactQuery持久化器遇window未定义错误求助

解决NextJS中ReactQuery持久化时"window is not defined"的问题

问题原因

NextJS采用服务端渲染(SSR),你的queryClient.ts模块会在服务端被加载执行,而服务端环境中不存在window对象,直接访问window.localStorage会触发错误。即便添加typeof window !== 'undefined'判断,模块解析阶段服务端仍会读取到window的引用,导致报错。

解决方案

将持久化逻辑移到客户端仅执行的生命周期中(比如useEffect),避免在服务端代码中直接访问window。

步骤1:修改queryClient.ts

只导出QueryClient实例,移除服务端无法执行的持久化代码:

import { QueryClient } from "react-query";

const cacheTime = 1000 * 60 * 60 * 24 * 5; // 5天

export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      cacheTime,
    },
  },
});

步骤2:在_app.tsx中添加客户端持久化逻辑

使用useEffect确保代码仅在客户端执行,同时初始化持久化:

import type { AppProps } from "next/app";
import "../styles/globals.css";
import { useEffect } from "react";
import { QueryClientProvider } from "react-query";
import { createWebStoragePersistor } from "react-query/createWebStoragePersistor-experimental";
import { persistQueryClient } from "react-query/persistQueryClient-experimental";
import { PokeDataContextProvider } from "@/context/PokeData";
import { queryClient } from "@/services/queryClient";

const cacheTime = 1000 * 60 * 60 * 24 * 5; // 和queryClient中保持一致

export default function App({ Component, pageProps }: AppProps) {
  useEffect(() => {
    const localStoragePersistor = createWebStoragePersistor({
      storage: window.localStorage,
    });

    persistQueryClient({
      queryClient,
      persistor: localStoragePersistor,
      maxAge: cacheTime,
    });
  }, []);

  return (
    <QueryClientProvider client={queryClient}>
      <PokeDataContextProvider>
        <Component {...pageProps} />
      </PokeDataContextProvider>
    </QueryClientProvider>
  );
}

补充说明

  • useEffect的回调函数只会在客户端渲染完成后执行,此时window对象已经存在,不会触发服务端报错。
  • 确保cacheTime在两处保持一致,避免持久化配置和查询缓存时间不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:45:14