Created
July 1, 2022 18:44
-
-
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.
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 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; |
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 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