Skip to content

Commit 5b9f801

Browse files
authored
Merge pull request #318 from wpengine/blog-query-cache
refactor: Blog query cache
2 parents b9da0a3 + 6413a78 commit 5b9f801

File tree

2 files changed

+77
-49
lines changed

2 files changed

+77
-49
lines changed

faust.config.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
1+
import { relayStylePagination } from "@apollo/client/utilities";
12
import { setConfig } from "@faustwp/core";
23
import possibleTypes from "./possibleTypes.json";
34
import templates from "./src/wp-templates";
45

6+
class PostTypePolicyPlugin {
7+
apply({ addFilter }) {
8+
addFilter(
9+
"apolloClientInMemoryCacheOptions",
10+
"faust",
11+
(inMemoryCacheObject) => {
12+
return {
13+
...inMemoryCacheObject,
14+
typePolicies: {
15+
Query: {
16+
fields: {
17+
posts: relayStylePagination(),
18+
},
19+
},
20+
},
21+
};
22+
},
23+
);
24+
}
25+
}
26+
527
/**
628
* @type {import('@faustwp/core').FaustConfig}
729
*/
830
export default setConfig({
931
templates,
10-
plugins: [],
32+
plugins: [new PostTypePolicyPlugin()],
1133
possibleTypes,
1234
usePersistedQueries: true,
1335
});

src/pages/blog/index.jsx

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { gql, useQuery } from "@apollo/client";
22
import { getNextStaticProps } from "@faustwp/core";
33
import { ArrowPathIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
44
import Link from "next/link";
5-
import { useState, useEffect } from "react";
5+
import { useState } from "react";
66
import Card from "@/components/card";
77
import Date from "@/components/date";
88
import Seo from "@/components/seo";
@@ -16,6 +16,7 @@ const GET_POSTS = gql`
1616
}
1717
edges {
1818
node {
19+
id
1920
title
2021
excerpt
2122
date
@@ -29,28 +30,18 @@ const GET_POSTS = gql`
2930

3031
const BATCH_SIZE = 12;
3132
export default function BlogIndex() {
32-
const { data, loading, error, fetchMore } = useQuery(GET_POSTS, {
33-
variables: { first: BATCH_SIZE, after: undefined },
33+
const {
34+
data,
35+
loading = true,
36+
error,
37+
fetchMore,
38+
} = useQuery(GET_POSTS, {
39+
// eslint-disable-next-line unicorn/no-null
40+
variables: { first: BATCH_SIZE, after: null },
3441
notifyOnNetworkStatusChange: true,
3542
fetchPolicy: "cache-and-network",
3643
});
3744

38-
const [posts, setPosts] = useState([]);
39-
const [loadingMore, setLoadingMore] = useState(false);
40-
const [cursor, setCursor] = useState(false);
41-
const [hasMorePosts, setHasMorePosts] = useState(true);
42-
43-
useEffect(() => {
44-
if (data) {
45-
setPosts((previousPosts) => [
46-
...previousPosts,
47-
...data.posts.edges.map((edge) => edge.node),
48-
]);
49-
setCursor(data.posts.pageInfo.endCursor);
50-
setHasMorePosts(data.posts.pageInfo.hasNextPage);
51-
}
52-
}, [data]);
53-
5445
if (loading && !data)
5546
return (
5647
<div className="container-main flex justify-center py-20">
@@ -65,21 +56,12 @@ export default function BlogIndex() {
6556
}
6657

6758
const loadMorePosts = async () => {
68-
setLoadingMore(true);
69-
const { data: moreData } = await fetchMore({
59+
await fetchMore({
7060
variables: {
7161
first: BATCH_SIZE,
72-
after: cursor,
62+
after: data.posts.pageInfo.endCursor,
7363
},
7464
});
75-
76-
setPosts((previousPosts) => [
77-
...previousPosts,
78-
...moreData.posts.edges.map((edge) => edge.node),
79-
]);
80-
setCursor(moreData.posts.pageInfo.endCursor);
81-
setHasMorePosts(moreData.posts.pageInfo.hasNextPage);
82-
setLoadingMore(false);
8365
};
8466

8567
return (
@@ -96,7 +78,7 @@ export default function BlogIndex() {
9678
Faust.js news
9779
</h1>
9880
<ul className="mt-8 grid list-none auto-rows-max grid-cols-6 gap-4 pl-0 md:grid-cols-12 md:gap-6 xl:gap-8">
99-
{posts.map((post) => (
81+
{data.posts.edges.map(({ node: post }) => (
10082
<Card
10183
as="li"
10284
className="group relative col-span-full flex flex-col rounded-2xl p-4 shadow-gray-900 transition duration-100 hover:bg-gray-900 hover:shadow-xl hover:ring-blue-600/40 md:col-span-6 md:p-6 lg:col-span-4 lg:p-8"
@@ -119,30 +101,54 @@ export default function BlogIndex() {
119101
</Card>
120102
))}
121103
</ul>
122-
{hasMorePosts && (
104+
{data.posts.pageInfo.hasNextPage && (
123105
<div className="mt-8 flex justify-center">
124-
<button
125-
type="button"
126-
className="flex cursor-pointer items-center rounded-sm bg-purple-700 px-4 py-2 text-white transition ease-in-out hover:bg-purple-800"
127-
onClick={loadMorePosts}
128-
disabled={loadingMore}
129-
>
130-
{loadingMore ? (
131-
<>
132-
Loading <ArrowPathIcon className="ml-2 h-5 w-5 animate-spin" />
133-
</>
134-
) : (
135-
<>
136-
Load more <ChevronDownIcon className="ml-2 h-5 w-5" />
137-
</>
138-
)}
139-
</button>
106+
<LoadMoreButton onClick={loadMorePosts} />
140107
</div>
141108
)}
142109
</main>
143110
);
144111
}
145112

113+
const LoadMoreButton = ({ onClick }) => {
114+
const [loading, setLoading] = useState(false);
115+
116+
const handleLoadMore = async () => {
117+
setLoading(true);
118+
await onClick();
119+
setLoading(false);
120+
};
121+
122+
return (
123+
<button
124+
type="button"
125+
className="flex cursor-pointer items-center rounded-sm bg-purple-700 px-4 py-2 text-white transition ease-in-out hover:bg-purple-800"
126+
onClick={handleLoadMore}
127+
disabled={loading}
128+
>
129+
{loading ? (
130+
<>
131+
Loading <ArrowPathIcon className="ml-2 h-5 w-5 animate-spin" />
132+
</>
133+
) : (
134+
<>
135+
Load more <ChevronDownIcon className="ml-2 h-5 w-5" />
136+
</>
137+
)}
138+
</button>
139+
);
140+
};
141+
142+
BlogIndex.query = GET_POSTS;
143+
144+
BlogIndex.variables = () => {
145+
return {
146+
// eslint-disable-next-line unicorn/no-null
147+
after: null,
148+
first: BATCH_SIZE,
149+
};
150+
};
151+
146152
export async function getStaticProps(context) {
147153
return getNextStaticProps(context, {
148154
Page: BlogIndex,

0 commit comments

Comments
 (0)