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

React Query 显示错误端点数据问题排查求助

问题排查:切换体育项目页面时React Query数据未更新

我正在开发一款多体育项目数据获取与渲染应用,采用React Query + Axios实现数据请求,封装了通用请求函数适配不同项目的API结构。

核心代码实现

URL与请求封装函数

const getBaseURL = (sport: Sports) => {
  switch (sport) {
    case "basketball":
    case "baseball":
    case "rugby":
    case "hockey":
      return `https://v1.${sport}.api-sports.io`;
    case "football":
      return `https://v3.football.api-sports.io`;
    default:
      return "";
  }
};

const getHost = (sport: Sports) => {
  switch (sport) {
    case "basketball":
    case "baseball":
    case "rugby":
    case "hockey":
      return `v1.${sport}.api-sports.io`;
    case "football":
      return `v3.football.api-sports.io`;
    default:
      return "";
  }
};

function createAxiosInstance(baseURL: string, headers: Record<string, string>) {
  return axios.create({
    baseURL: baseURL,
    headers: headers,
  });
}

export const getFixturesByDate = async (date: string, sport: Sports) => {
  const baseURL = getBaseURL(sport);
  const headers = {
    "x-rapidapi-host": getHost(sport),
    "x-rapidapi-key":
      process.env.RAPIDAPI_KEY ?? process.env.NEXT_PUBLIC_RAPIDAPI_KEY!,
  };
  const axiosInstance = createAxiosInstance(baseURL, headers);

  switch (sport) {
    case "basketball":
      return (
        await axiosInstance.get<APIResponse<Games<BasketballScores>>>(
          `/games?date=${date}`
        )
      ).data.response;
    case "baseball":
      return (
        await axiosInstance.get<APIResponse<Games<BaseballScores>>>(
          `/games?date=${date}`
        )
      ).data.response;
    case "rugby":
      return (
        await axiosInstance.get<APIResponse<GamesWithPeriods<number | null>>>(
          `/games?date=${date}`
        )
      ).data.response;
    case "hockey":
      return (
        await axiosInstance.get<
          APIResponse<GamesWithPeriodsAndEvents<number | null>>
        >(`/games?date=${date}`)
      ).data.response;
    case "football":
      return (
        await axiosInstance.get<APIResponse<Fixtures>>(`/fixtures?date=${date}`)
      ).data.response;
    default:
      return undefined;
  }
};

React Query自定义Hook

export function useFixturesByDate(date: string, sport: Sports) {
  return useQuery({
    queryKey: [sport, "fixtures", date],
    queryFn: () => getFixturesByDate(date, sport),
    staleTime: 5 * 60 * 1000,
    enabled: !!date || !!sport,
  });
}

HomeFixtures组件

const HomeFixtures = ({ sport }: Props) => {
  const { status } = useStatusStore();
  const { date } = useDateStore();
  const { league } = useLeagueStore();
  const formattedDate = format(date, "yyyy-MM-dd");

  const { data, isFetching, isError, error } = useFixturesByDate(
    formattedDate,
    sport
  );

// rest of the code
};

页面调用(Next.js App Router)

篮球页面:

<div className="h-[calc(100vh-150px)] overflow-y-auto px-6">
  <HomeFixtures sport={"basketball"} />
</div>

棒球页面:

<div className="h-[calc(100vh-150px)] overflow-y-auto px-6">
  <HomeFixtures sport={"baseball"} />
</div>

问题现象

切换体育项目页面时,自定义Hook虽被调用,但React Query DevTools仍显示前一项目(如篮球)的数据,仅手动点击重新获取才能加载当前项目的正确数据。

问题排查与解决方案

1. 修复useQuery的enabled条件

当前enabled: !!date || !!sport的逻辑存在错误:只要date或sport任一存在就启用请求,这会导致当其中一个参数无效时仍发起请求,甚至可能干扰新请求的触发。

应修改为同时满足date和sport有效才启用请求:

enabled: !!date && !!sport,

这样只有当两个参数都存在时,才会发起请求,避免无效请求干扰缓存逻辑。

2. 验证queryKey的唯一性

当前queryKey为[sport, "fixtures", date],理论上不同sport会生成不同的queryKey,不会共享缓存。可在useFixturesByDate中添加日志,确认切换页面时sport参数是否正确更新:

export function useFixturesByDate(date: string, sport: Sports) {
  console.log("Current sport:", sport);
  console.log("Query key:", [sport, "fixtures", date]);
  return useQuery({
    // ... 其他配置
  });
}

若日志显示sport未正确更新,需检查页面组件的props传递是否存在问题。

3. 确认组件渲染环境

确保HomeFixtures组件是客户端组件(在文件顶部添加'use client'指令),因为React Query的hooks仅能在客户端组件中使用。若为服务器组件,useQuery无法正常工作,会导致数据不更新。

4. 检查staleTime配置

当前staleTime为5分钟,这意味着数据在5分钟内会被认为是新鲜的,但由于不同sport的queryKey不同,不会复用旧数据。若仍存在缓存问题,可临时将staleTime设为0进行测试,排除缓存影响:

staleTime: 0,

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:04:50