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

如何通过React Query监听语言变化,自动触发API重新请求?

解决方案:全局处理语言变更触发React Query自动重新请求

针对你的需求,有两种无需逐个修改useQuery的全局方案,以下是具体实现:

方案一:订阅语言状态变化,批量失效相关查询

利用Zustand的状态订阅能力,在语言切换时调用React Query的invalidateQueries方法,批量失效需要更新的查询。

步骤1:创建全局QueryClient实例

先单独维护一个全局的queryClient,方便在状态管理中调用:

// queryClient.ts
import { QueryClient } from '@tanstack/react-query';

export const queryClient = new QueryClient();

步骤2:在Zustand Store中集成查询失效逻辑

直接在语言切换的方法里触发查询失效,无需在组件中额外写useEffect:

import { create } from 'zustand';
import { queryClient } from './queryClient';

interface LanguageState {
  lang: string;
  setLang: (lang: string) => void;
}

export const useLanguageStore = create<LanguageState>((set) => ({
  lang: 'en',
  setLang: (lang) => {
    set({ lang });
    // 只失效API相关的查询(根据你的查询键前缀调整)
    queryClient.invalidateQueries({
      predicate: (query) => query.queryKey[0] === 'api'
    });
    // 如果所有查询都需要更新,直接用:queryClient.invalidateQueries()
  },
}));

步骤3:确保Axios拦截器正确获取最新语言

拦截器中用Zustand的getState()获取当前语言(不能用钩子,因为拦截器不在React组件树中):

import axios from 'axios';
import { useLanguageStore } from './stores/languageStore';

const api = axios.create({ baseURL: '/api' });

api.interceptors.request.use((config) => {
  const lang = useLanguageStore.getState().lang;
  config.headers['Accept-Language'] = lang;
  return config;
});

方案二:全局给查询键自动添加语言参数

通过自定义钩子,给所有查询键自动注入当前语言,让React Query将不同语言的数据视为独立查询,自动触发重新请求。

实现:自定义全局useQuery钩子

创建一个封装好的useLangQuery,替代原生useQuery,自动将语言加入查询键:

import { useQuery, UseQueryOptions } from '@tanstack/react-query';
import { useLanguageStore } from './stores/languageStore';

export function useLangQuery<
  TQueryFnData = unknown,
  TError = unknown,
  TData = TQueryFnData,
  TQueryKey extends any[] = any[]
>(
  queryKey: TQueryKey,
  queryFn: () => Promise<TQueryFnData>,
  options?: Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey' | 'queryFn'>
) {
  const lang = useLanguageStore((state) => state.lang);
  return useQuery({
    queryKey: [...queryKey, lang],
    queryFn,
    ...options,
  });
}

之后所有业务代码中直接使用useLangQuery替代useQuery即可,无需手动添加语言依赖:

// 示例使用
function usePosts() {
  return useLangQuery(
    ['posts'],
    () => api.get('/posts').then(res => res.data)
  );
}

两种方案对比

方案一(批量失效)方案二(查询键注入)
无需修改现有useQuery代码需要替换所有useQuery为自定义钩子
切换语言时会重新请求数据(无缓存复用)不同语言的数据会分开缓存,切换回已请求过的语言时直接读缓存
可精准控制哪些查询需要更新所有使用自定义钩子的查询都会自动处理语言依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:42:04