Last active
February 16, 2020 20:55
-
-
Save saleebm/8f8838c35c6c936635f6bf7efc0b16d3 to your computer and use it in GitHub Desktop.
Pagination woes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useQuery } from "@apollo/react-hooks"; | |
import { NetworkStatus } from "@apollo/client"; | |
import gql from "graphql-tag"; | |
import ErrorMessage from "./ErrorMessage"; | |
export const ALL_POSTS_QUERY = gql` | |
query GET_ALL_PRODUCTS_PAGES( | |
$first: Int | |
$after: String | |
$last: Int | |
$before: String | |
) { | |
products(first: $first, after: $after, last: $last, before: $before) { | |
pageInfo { | |
endCursor | |
startCursor | |
hasNextPage | |
hasPreviousPage | |
} | |
edges { | |
cursor | |
node { | |
name | |
productId | |
} | |
} | |
} | |
} | |
`; | |
const allPostsQueryVars = { | |
first: 10 | |
}; | |
export default function PostList() { | |
const { loading, error, data, fetchMore, networkStatus } = useQuery( | |
ALL_POSTS_QUERY, | |
{ | |
variables: allPostsQueryVars, | |
// Setting this value to true will make the component rerender when | |
// the "networkStatus" changes, so we are able to know if it is fetching | |
// more data | |
notifyOnNetworkStatusChange: true | |
} | |
); | |
const loadingMorePosts = networkStatus === NetworkStatus.fetchMore; | |
const loadMorePosts = () => { | |
fetchMore({ | |
variables: { | |
first: 10, | |
last: null, | |
after: data["products"]?.pageInfo?.endCursor | |
}, | |
updateQuery: (previousResult, { fetchMoreResult }) => { | |
if (!fetchMoreResult) return previousResult; | |
const newEdges = fetchMoreResult.products?.edges; | |
const pageInfo = fetchMoreResult.products?.pageInfo; | |
return newEdges?.length && previousResult?.products && pageInfo | |
? { | |
products: { | |
__typename: previousResult.products?.__typename, | |
edges: [...newEdges], | |
pageInfo | |
} | |
} | |
: previousResult; | |
} | |
}); | |
}; | |
const loadLessPosts = () => { | |
fetchMore({ | |
variables: { | |
first: null, | |
last: 10, | |
before: data["products"]?.pageInfo?.startCursor | |
}, | |
updateQuery: (previousResult, { fetchMoreResult }) => { | |
if (!fetchMoreResult) return previousResult; | |
const newEdges = fetchMoreResult.products?.edges; | |
const pageInfo = fetchMoreResult.products?.pageInfo; | |
return newEdges?.length && previousResult?.products && pageInfo | |
? { | |
products: { | |
__typename: previousResult.products?.__typename, | |
edges: [...newEdges], | |
pageInfo | |
} | |
} | |
: previousResult; | |
} | |
}); | |
}; | |
if (error) return <ErrorMessage message="Error loading posts." />; | |
if (loading && !loadingMorePosts) return <div>Loading</div>; | |
return ( | |
<section> | |
{data?.products?.edges?.map(edge => ( | |
<div key={edge.node.id}>{edge.node.name}</div> | |
))} | |
{data && data["products"]?.pageInfo?.hasNextPage && ( | |
<button onClick={() => loadMorePosts()} disabled={loadingMorePosts}> | |
{loadingMorePosts ? "Loading..." : "Show More"} | |
</button> | |
)} | |
{data && data["products"]?.pageInfo?.hasPreviousPage && ( | |
<button onClick={() => loadLessPosts()} disabled={loadingMorePosts}> | |
{loadingMorePosts ? "Loading..." : "Show Less"} | |
</button> | |
)} | |
<style jsx>{` | |
section { | |
padding-bottom: 20px; | |
} | |
li { | |
display: block; | |
margin-bottom: 10px; | |
} | |
div { | |
align-items: center; | |
display: flex; | |
} | |
a { | |
font-size: 14px; | |
margin-right: 10px; | |
text-decoration: none; | |
padding-bottom: 0; | |
border: 0; | |
} | |
span { | |
font-size: 14px; | |
margin-right: 5px; | |
} | |
ul { | |
margin: 0; | |
padding: 0; | |
} | |
button:before { | |
align-self: center; | |
border-style: solid; | |
border-width: 6px 4px 0 4px; | |
border-color: #ffffff transparent transparent transparent; | |
content: ""; | |
height: 0; | |
margin-right: 5px; | |
width: 0; | |
} | |
`}</style> | |
</section> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
use the WordPress GraphQL endpoint with WooCommerce extension enabled.
replace the PostList file with the one above.
In the page components, remove the comments and other components so you don't get errors.