REST API at https://jsonplaceholder.typicode.com/posts for testing
What is Axios?
https://axios-http.com/docs/intro
Axios is a promise-based HTTP Client for node.js and the browser. It is isomorphic (= it can run in the browser and nodejs with the same codebase). On the server-side it uses the native node.js http module, while on the client (browser) it uses XMLHttpRequests.
Installing Using npm: $ npm install axios
src/index.js
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'
ReactDOM.render(
<App />,
document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ReactJS </title>
</head>
<body>
<div id="root"></div>
</body>
</html>
src/index.css
//src/index.css
.pagination-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
font-weight: 500;
font-size: 15px;
}
.pagination-container a {
display: flex;
justify-content: center;
align-items: center;
color: black;
height: 40px;
width: 40px;
text-decoration: none;
transition: background-color .2s;
border: 1px solid #ddd;
cursor: pointer;
}
.pagination-container a.active {
background-color: #007bff;
color: white;
border: 1px solid #7cbddb;
}
.pagination-container a.disabled {
opacity: 0.2;
}
.pagination-container a:hover:not(.active) {background-color: rgb(238, 238, 238);}
src/App.js
//src/App.js
import React, { useState, useEffect } from 'react';
import Pagination from './Pagination'
import axios from 'axios'
function App() {
const [posts, setPosts] = useState([])
const [loading, setLoading] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const [postsPerPage] = useState(7) //7 Per Page
useEffect(() => {
const fetchPosts = async () => {
setLoading(true)
const res = await axios.get('https://jsonplaceholder.typicode.com/posts')
setPosts(res.data)
setLoading(false)
}
fetchPosts()
}, [])
if (loading && posts.length === 0) {
return <h2>Loading...</h2>
}
//Get current posts
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost)
const howManyPages = Math.ceil(posts.length/postsPerPage)
return (
<div className="container" style={{padding: 20}}>
<h4 className="d-inline-block">ReactJS Pagination - React axios.get</h4>
<table className="table table-striped">
<thead className="thead-light ">
<th>ID</th>
<th>Title</th>
<th>Body</th>
</thead>
<tbody>
{currentPosts.map(row => <tr>
<td>{row.id}</td>
<td>{row.title}</td>
<td>{row.body}</td>
</tr>)}
</tbody>
</table>
<Pagination pages = {howManyPages} setCurrentPage={setCurrentPage}/>
</div>
);
}
export default App;
src/Pagination.js
//src/Pagination.js
import React, { useState, useEffect } from 'react';
function Pagination({ pages = 7, setCurrentPage }) {
//Set number of pages
const numberOfPages = []
for (let i = 1; i <= pages; i++) {
numberOfPages.push(i)
}
// Current active button number
const [currentButton, setCurrentButton] = useState(1)
// Array of buttons what we see on the page
const [arrOfCurrButtons, setArrOfCurrButtons] = useState([])
useEffect(() => {
let tempNumberOfPages = [...arrOfCurrButtons]
let dotsInitial = '...'
let dotsLeft = '... '
let dotsRight = ' ...'
if (numberOfPages.length < 6) {
tempNumberOfPages = numberOfPages
}
else if (currentButton >= 1 && currentButton <= 3) {
tempNumberOfPages = [1, 2, 3, 4, dotsInitial, numberOfPages.length]
}
else if (currentButton === 4) {
const sliced = numberOfPages.slice(0, 5)
tempNumberOfPages = [...sliced, dotsInitial, numberOfPages.length]
}
else if (currentButton > 4 && currentButton < numberOfPages.length - 2) {
const sliced1 = numberOfPages.slice(currentButton - 2, currentButton)
const sliced2 = numberOfPages.slice(currentButton, currentButton + 1)
tempNumberOfPages = ([1, dotsLeft, ...sliced1, ...sliced2, dotsRight, numberOfPages.length])
}
else if (currentButton > numberOfPages.length - 3) {
const sliced = numberOfPages.slice(numberOfPages.length - 4)
tempNumberOfPages = ([1, dotsLeft, ...sliced])
}
else if (currentButton === dotsInitial) {
setCurrentButton(arrOfCurrButtons[arrOfCurrButtons.length-3] + 1)
}
else if (currentButton === dotsRight) {
setCurrentButton(arrOfCurrButtons[3] + 2)
}
else if (currentButton === dotsLeft) {
setCurrentButton(arrOfCurrButtons[3] - 2)
}
setArrOfCurrButtons(tempNumberOfPages)
setCurrentPage(currentButton)
}, [currentButton])
return (
<div className="pagination-container">
<a
href="#"
className={`${currentButton === 1 ? 'disabled' : ''}`}
onClick={() => setCurrentButton(prev => prev <= 1 ? prev : prev - 1)}
>
Prev
</a>
{arrOfCurrButtons.map(((item, index) => {
return <a
href="#"
key={index}
className={`${currentButton === item ? 'active' : ''}`}
onClick={() => setCurrentButton(item)}
>
{item}
</a>
}))}
<a
href="#"
className={`${currentButton === numberOfPages.length ? 'disabled' : ''}`}
onClick={() => setCurrentButton(prev => prev >= numberOfPages.length ? prev : prev + 1)}
>
Next
</a>
</div>
);
}
export default Pagination
