Skip to content

Instantly share code, notes, and snippets.

@olawanlejoel
Created July 1, 2022 18:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olawanlejoel/97dec04da8ea12cf3cf5214791239725 to your computer and use it in GitHub Desktop.
Save olawanlejoel/97dec04da8ea12cf3cf5214791239725 to your computer and use it in GitHub Desktop.
How to perform Pagination with GraphCMS and React from Scratch using GraphQL to query data.
import React, { useState, useEffect } from 'react';
import { request } from 'graphql-request';
import Paginate from './Paginate';
const App = () => {
const [blogPosts, setBlogPosts] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [totalPosts, setTotalPosts] = useState();
const [postsPerPage] = useState(3);
useEffect(() => {
const fetchBlogPosts = async () => {
const { posts, postsConnection } = await request(
'https://api-us-east-1.graphcms.com/v2/cl3zo5a7h1jq701xv8mfyffi4/master',
`
{
posts (first: ${postsPerPage}, skip: ${
currentPage * postsPerPage - postsPerPage
}) {
id
title
excert
postUrl
cover {
url
}
datePublished
author {
firstName
profilePicture {
url
}
}
}
postsConnection {
pageInfo {
pageSize
}
}
}
`
);
setBlogPosts(posts);
setTotalPosts(postsConnection.pageInfo.pageSize);
};
fetchBlogPosts();
}, [currentPage, postsPerPage]);
const paginate = (pageNumber) => {
setCurrentPage(pageNumber);
};
const previousPage = () => {
if (currentPage !== 1) {
setCurrentPage(currentPage - 1);
}
};
const nextPage = () => {
if (currentPage !== Math.ceil(totalPosts / postsPerPage)) {
setCurrentPage(currentPage + 1);
}
};
return (
<div className="container">
<div className="title">
<h1>Blog</h1>
</div>
{blogPosts ? (
<div className="blog-content-section">
<div className="blog-container">
{blogPosts.map((blogPost) => (
<div className="blog-post" key={blogPost.id}>
<img className="cover-img" src={blogPost.cover.url} alt="" />
<h2 className="title">{blogPost.title}</h2>
<p className="description">{blogPost.excert}</p>
<div className="card-details">
<div className="lh-details">
<img
className="author-img"
src={blogPost.author.profilePicture.url}
alt=""
/>
<p className="date">
{new Date(`${blogPost.datePublished}`).toLocaleDateString(
'en-us',
{
year: 'numeric',
month: 'short',
day: 'numeric',
}
)}
</p>
</div>
<a
href={blogPost.postUrl}
target="_blank"
rel="noopener noreferrer"
className="read-more"
>
Read post
</a>
</div>
</div>
))}
</div>
<Paginate
postsPerPage={postsPerPage}
totalPosts={totalPosts}
currentPage={currentPage}
paginate={paginate}
previousPage={previousPage}
nextPage={nextPage}
/>
</div>
) : (
<div className="loading">Loading...</div>
)}
</div>
);
};
export default App;
import React from 'react';
const Paginate = ({
postsPerPage,
totalPosts,
currentPage,
paginate,
previousPage,
nextPage,
}) => {
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
return (
<div className="pagination-container">
<ul className="pagination">
<li onClick={previousPage} className="page-number">
Prev
</li>
{pageNumbers.map((number) => (
<li
key={number}
onClick={() => paginate(number)}
className={
'page-number ' + (number === currentPage ? 'active' : '')
}
>
{number}
</li>
))}
<li onClick={nextPage} className="page-number">
Next
</li>
</ul>
</div>
);
};
export default Paginate;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment