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

WPGraphQL查询变量未更新,Apollo加载更多功能失效排查

问题排查与修复方案

你的代码存在两个核心问题,导致“加载更多”功能失效:

1. 缺少fetchMore的updateQuery函数(最关键)

Apollo Client 的fetchMore不会自动合并分页查询结果,必须通过updateQuery手动将新获取的文章数据合并到现有数据集中。你的代码仅发起了新查询,但未更新缓存的数据集,因此页面不会展示新加载的内容。

2. fetchMore变量传递不完整(潜在问题)

虽然Apollo会合并现有变量,但显式传递first参数可避免因变量合并逻辑异常导致的查询错误。


修复后的完整代码

import { gql, useQuery } from '@apollo/client';
import Link from 'next/link';

const GET_POSTS = gql`
  query getPosts($first: Int!, $after: String) {
    posts(first: $first, after: $after) {
      pageInfo {
        hasNextPage
        endCursor
      }
      edges {
        node {
          id
          databaseId
          title
          slug
        }
      }
    }
  }
`;

const BATCH_SIZE = 5;

const PostsFilter = ({ content, ...props }) => {
  const { data, loading, error, fetchMore } = useQuery(GET_POSTS, {
    variables: { first: BATCH_SIZE, after: null },
    notifyOnNetworkStatusChange: true,
  });

  if (error) {
    return <p>Sorry, an error happened. Reload Please</p>;
  }

  if (!data && loading) {
    return <p>Loading...</p>;
  }

  if (!data?.posts.edges.length) {
    return <p>no posts have been published</p>;
  }

  const posts = data.posts.edges.map((edge) => edge.node);
  const haveMorePosts = Boolean(data?.posts?.pageInfo?.hasNextPage);

  const handleLoadMore = () => {
    fetchMore({
      // 显式传递所有必要查询变量
      variables: {
        first: BATCH_SIZE,
        after: data.posts.pageInfo.endCursor,
      },
      // 手动合并新旧数据,更新缓存
      updateQuery: (prevResult, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prevResult;
        return {
          posts: {
            ...fetchMoreResult.posts,
            edges: [...prevResult.posts.edges, ...fetchMoreResult.posts.edges],
          },
        };
      },
    });
  };

  return (
    <PostsFilterContainer {...props}>
      <div className="grid">
        <aside>
          <h3>Categories</h3>

          <div className="content white">
            <ul>
              {content.filtersToShow.map((filter) => {
                return <li key={filter.name}>{filter.name}</li>;
              })}
            </ul>
          </div>
        </aside>

        <div className="posts-wrapper">
          <ul>
            {posts.map((item) => {
              // 使用文章唯一ID作为key,避免列表渲染异常
              return <li key={item.databaseId}>{item.title}</li>;
            })}
          </ul>

          {haveMorePosts ? (
            <button onClick={handleLoadMore} disabled={loading}>
              {loading ? 'Loading...' : 'Load more'}
            </button>
          ) : (
            <p>✅ All posts loaded.</p>
          )}
        </div>
      </div>
    </PostsFilterContainer>
  );
};

export default PostsFilter;

额外优化说明

  • 移除了不必要的form标签,直接用按钮onClick触发加载,简化逻辑
  • 将列表项的key从索引改为文章databaseId,保证列表渲染稳定性
  • 抽离独立的handleLoadMore函数,提升代码可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:13:13