reactjsgraphqlapolloapollo-clientwp-graphql

WPGraphQL query variables not updating data


I'm trying to add a "Load More" feature to my blog posts page using Apollo/GraphQL/React, and am following the exact instructions founds here. However when I click on the load more button, it doesn't load any additional posts, and doesn't seem to update the query variables either. Is there a reason in the code below that this wouldn't be working?

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 }) => {
  // console.log('PostsFilter Content', content);

  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);

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

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

        <div className="posts-wrapper">
          <ul>
            {posts.map((item, i) => {
              return <li key={i}>{item.title}</li>;
            })}
          </ul>

          {haveMorePosts ? (
            <form
              method="post"
              onSubmit={(event) => {
                event.preventDefault();
                fetchMore({ variables: { after: data.posts.pageInfo.endCursor } });
              }}
            >
              <button type="submit" disabled={loading}>
                {loading ? 'Loading...' : 'Load more'}
              </button>
            </form>
          ) : (
            <p>✅ All posts loaded.</p>
          )}
        </div>
      </div>
    </PostsFilterContainer>
  );
};

export default PostsFilter;

Solution

  • fetchMore({
      variables: { after: data.posts.pageInfo.endCursor },
      updateQuery: (prevResult, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prevResult;
        return {
          posts: {
            ...fetchMoreResult.posts,
            edges: [
              ...prevResult.posts.edges,
              ...fetchMoreResult.posts.edges,
            ],
          },
        };
      },
    });