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

Apollo Client查询变量变更时缓存未更新,分页返回上页数据异常

问题原因

  • 核心原因是你直接通过window.location读取路由参数,该取值方式不是React响应式的,路由跳转时LinkList组件不会触发重渲染,page变量一直停留在组件首次挂载时的值,导致useQuery接收的variables始终没有更新,Apollo自然不会拉取对应页码的新数据,也不会从缓存中读取上一页的对应数据。
  • 次要潜在原因:如果你的Apollo Client没有配置分页字段的缓存合并策略,不同页码的查询结果可能会互相覆盖,就算变量更新也会出现数据异常。

修复步骤

步骤1:替换路由参数读取逻辑

使用react-router提供的useParams钩子读取页码参数,确保路由变化时组件能响应式拿到最新页码,触发重渲染并更新查询变量。

步骤2:(可选)配置Apollo缓存策略

如果修改参数读取逻辑后仍有缓存问题,给分页字段配置合并策略,或者给useQuery指定合适的拉取策略。

修改后参考代码

import React from "react";
import Link from "./Link";
import { useQuery } from "@apollo/client";
import { useNavigate, useParams, useLocation } from "react-router-dom";
import { LINKS_PER_PAGE } from "../utilities/constants";
import FEED_QUERY from "../graphql/queries/feedLinks";
import getQueryVariables from "../utilities/getQueryVariables";
import getLinksToRender from "../utilities/getLinksToRender";

const LinkList = () => {
  const navigate = useNavigate();
  const { pathname } = useLocation();
  // 用useParams读取路由里的page参数,无需自行切割路径
  const { page: pageParam } = useParams();
  const page = parseInt(pageParam) || 1;

  const isNewPage = pathname.includes("new");
  const pageIndex = (page - 1) * LINKS_PER_PAGE;

  const { data, loading, error} = useQuery(FEED_QUERY, {
    variables: getQueryVariables(isNewPage, page),
    // 如果还有缓存问题可以去掉下方注释,优先用缓存无匹配数据再发请求
    // fetchPolicy: "cache-first"
  });

  return (
    <>
      {loading && <p>Loading...</p>}
      {error && <pre>{JSON.stringify(error, null, 2)}</pre>}
      {data && (
        <>
          {getLinksToRender(isNewPage, data).map((link, index) => (
            <Link key={link.id} link={link} index={index + pageIndex} />
          ))}
          {isNewPage && (
            <div className="flex ml4 mv3 gray">
              <div
                className="pointer mr2"
                onClick={() => {
                  if (page > 1) {
                    navigate(`/new/${page - 1}`);
                  }
                }}
              >
                Previous
              </div>
              <div
                className="pointer"
                onClick={() => {
                  if (page < data.feed.count / LINKS_PER_PAGE) {
                    const nextPage = page + 1;
                    navigate(`/new/${nextPage}`);
                  }
                }}
              >
                Next
              </div>
            </div>
          )}
        </>
      )}
    </>
  );
};

export default LinkList;

如果确认是缓存合并导致的问题,可在初始化Apollo Client时添加如下配置:

import { InMemoryCache, ApolloClient } from "@apollo/client";

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        feed: {
          keyArgs: false,
          merge(existing = { links: [] }, incoming) {
            return {
              ...incoming,
              links: [...existing.links, ...incoming.links]
            }
          }
        }
      }
    }
  }
})

const client = new ApolloClient({
  // 其余客户端配置
  cache
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:15:07