Reputation: 353
I have an array of 12 objects of a list of movies and i want to create pagination for them using React paginate by displaying 4 items for each page, I already display the items on the UI but the numbers of pages didn't work even when I click on the Next button.
it is my first experience with pagination in react.
import './App.css';
import React,{useState} from 'react';
import MoviesData from './components/Data/MoviesData';
import ReactPaginate from 'react-paginate';
function App() {
const [categories, setCategories] = useState(allCategories);
const [moviesList, setMoviesList] = useState(MoviesData.slice(0, 4));
const [pageNumber, setPageNumber] = useState(0);
const moviePerPage = 4;
//to determinate how many pages we going to have
const pageCount = Math.ceil(moviesList.length / moviePerPage);
const changePage = ({ selected }) => {
setPageNumber(selected);
};
return (
<main>
<MoviesCards moviesList ={moviesList} removeMovie={removeMovie} />
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
pageCount={pageCount}
onPageChange={changePage}
containerClassName={"paginationBttns"}
previousLinkClassName={"previousBttn"}
nextLinkClassName={"nextBttn"}
disabledClassName={"paginationDisabled"}
activeClassName={"paginationActive"}
/>
</main>
)
}
export default App;
This component where i display my items :
import React from 'react';
import SingleMovieCard from '../SingleMovieCard/SingleMovieCard';
const MoviesCards = ({moviesList}) => {
return (
<section>
<div className="title">
<h2>Welcome to the box office</h2>
</div>
<div >
{moviesList.map((singleMovie)=> {
return(
<SingleMovieCard singleMovie={singleMovie}
key={singleMovie.id}
removeMovie={removeMovie} />
)
})}
</div>
</section>
)
}
export default MoviesCards;
Upvotes: 0
Views: 795
Reputation: 1051
There is some problems. I will list it here:
const pageCount = Math.ceil(moviesList.length / moviePerPage);
should be:
const pageCount = Math.ceil(MoviesData.length / moviePerPage);
That's because your page count is relative to whole movie count not only the page count, which is your state storing
Another problem is with your page management, the first is ok, however every time you change your page you need to set it with the new list of movies. That means you need an useEffect
to track changes in pageNumber
and then set your moviesList
, something like this:
useEffect(() => {
setMoviesList(MoviesData.slice(pageNumber * 4, (pageNumber + 1) * 4));
}, [pageNumber]);
I've done a simple case:
import React, { useEffect, useState } from "react";
import ReactPaginate from "react-paginate";
const MoviesData = [
{ title: "Foo", category: "horror" },
{ title: "Foo1", category: "horror" },
{ title: "Foo2", category: "horror" },
{ title: "Foo3", category: "horror" },
{ title: "Bar", category: "horror" },
{ title: "Bar1", category: "horror" },
{ title: "Bar2", category: "horror" },
{ title: "Bar3", category: "horror" }
];
const SingleMovieCard = ({ singleMovie }) => {
return <div>{singleMovie.title}</div>;
};
const MoviesCards = ({ moviesList }) => {
return (
<section>
<div className="title">
<h2>Welcome to the box office</h2>
</div>
<div>
{moviesList.map((singleMovie) => {
return (
<SingleMovieCard singleMovie={singleMovie} key={singleMovie.id} />
);
})}
</div>
</section>
);
};
function App() {
const [pageNumber, setPageNumber] = useState(0);
const [moviesList, setMoviesList] = useState(MoviesData.slice(0, 4));
const moviePerPage = 4;
const pageCount = Math.ceil(MoviesData.length / moviePerPage);
useEffect(() => {
setMoviesList(MoviesData.slice(pageNumber * 4, (pageNumber + 1) * 4));
}, [pageNumber]);
const changePage = ({ selected }) => {
console.log(selected);
setPageNumber(selected);
};
return (
<main>
<MoviesCards moviesList={moviesList} />
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
pageCount={pageCount}
onPageChange={changePage}
containerClassName={"paginationBttns"}
previousLinkClassName={"previousBttn"}
nextLinkClassName={"nextBttn"}
disabledClassName={"paginationDisabled"}
activeClassName={"paginationActive"}
/>
</main>
);
}
export default App;
Upvotes: 1