Howdy! I’m relatively new to GraphQL & Apollo and I’ve been stuck the past few days trying to figure out how to get caching to work with relay-style pagination.
(My first post got eaten so fingers crossed!)
I’ve included a gif below. You can see the updated (merged, not overwritten) and yet it doesn’t appear that we’re reading from the cache.
Code
The code is very basic. I’m hoping to get this working as I expect before building it out.
In my main script:
import React from "react";
import ReactDOM from "react-dom";
import PostFeed from "../_components/feeds/PostFeed";
document.addEventListener( "DOMContentLoaded", () => {
const renderedFeed = document.querySelector( '.post-feed-app' );
ReactDOM.render(
<PostFeed />,
renderedFeed
);
} ); // End on DOMContentLoaded.
Query
/*--------------------------------------------------------------
# Define Main Query
--------------------------------------------------------------*/
const GET_POSTS_QUERY = gql`
query MorePosts(
$first: Int
$last: Int
$after: String
$before: String
) {
posts(
first: $first,
last: $last,
after: $after,
before: $before
) {
edges {
node {
id
databaseId
title
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
`;
Components
import {
ApolloClient,
ApolloProvider,
InMemoryCache,
useQuery,
gql
} from "@apollo/client";
import { relayStylePagination } from "@apollo/client/utilities";
const perPage = 5;
/*--------------------------------------------------------------
# Define Client
--------------------------------------------------------------*/
const relayCacheOptions = {
typePolicies: {
Query: {
fields: {
posts: relayStylePagination(),
}
}
}
};
const client = new ApolloClient( {
uri: 'https://testingblocks.local/graphql', /* local path */
cache: new InMemoryCache( relayCacheOptions )
} );
/*--------------------------------------------------------------
# Define Main Query
--------------------------------------------------------------*/
const GET_POSTS_QUERY = gql`
# See above
`
/*--------------------------------------------------------------
# Define `updateQuery` - update the query with the new results
--------------------------------------------------------------*/
const updateQuery = (previousResult, { fetchMoreResult }) => {
return fetchMoreResult.posts.edges.length ? fetchMoreResult : previousResult;
};
/*--------------------------------------------------------------
# Define Postlist - Component that shows the paginated list of posts
--------------------------------------------------------------*/
const PostList = ({ data, fetchMore }) => {
const { posts } = data;
return (
<div>
{posts && posts.edges ? (
<div>
<ul>
{posts.edges.map(edge => {
const { node } = edge;
return (
<li key={node.id}>
{node.title}
</li>
);
})}
</ul>
<div>
{posts.pageInfo.hasPreviousPage ? (
<button
onClick={() => {
fetchMore({
variables: {
first: null,
after: null,
last: perPage,
before: posts.pageInfo.startCursor || null
},
updateQuery
});
}}
>
Previous
</button>
) : null}
{posts.pageInfo.hasNextPage ? (
<button
onClick={() => {
fetchMore({
variables: {
first: perPage,
after: posts.pageInfo.endCursor || null,
last: null,
before: null
},
updateQuery
});
}}
>
Next
</button>
) : null}
</div>
</div>
) : (
<div>No posts were found...</div>
)}
</div>
);
};
/*--------------------------------------------------------------
# Define Posts
--------------------------------------------------------------*/
function Posts() {
const variables = {
first: perPage,
last: null,
after: null,
before: null
};
const { data, error, loading, fetchMore } = useQuery(
GET_POSTS_QUERY, {
variables,
notifyOnNetworkStatusChange: true
}
);
if (error) {
return <pre>{JSON.stringify(error)}</pre>;
}
if (loading) {
return <p><i>Loading...</i></p>;
}
console.log({data});
return (
<PostList
data={data}
fetchMore={fetchMore}
/>
);
};
/*--------------------------------------------------------------
# Final component
--------------------------------------------------------------*/
export default function PostFeed() {
console.log({client})
return (
<ApolloProvider client={client}>
<div>
<h2>Post List</h2>
<Posts />
</div>
</ApolloProvider>
);
}
Thank you for taking the time to read this! I’m hoping it’s something obvious. Please let me know if you have any questions, I’m happy to provide more context. Thanks again!
References used:
https://www.wpgraphql.com/2020/03/26/forward-and-backward-pagination-with-wpgraphql