'REACT - Pagination does not works as I expected
I know the question is not qualitative but to be honest I don't know how to fix this. We have part of the React code:
import { useState } from 'react';
import { useGetBooks } from '../../hooks/useGetBooks';
import { BookType } from '../../types/Book';
import { SingleBook } from './SingleBook';
import styled from 'styled-components';
import ReactPaginate from 'react-paginate';
import { Navbar } from './Navbar';
import { useRecoilValue } from 'recoil';
import { SearchInputState } from '../../recoil/globalState';
import { Loader } from '../utilities/Loader';
import { Error } from '../utilities/Error';
type bookType = BookType;
export const BookList = () => {
const { isLoading, isError, data } = useGetBooks();
const searchInputValue = useRecoilValue(SearchInputState);
const [pageNumber, setPageNumber] = useState(0);
if (isLoading) {
return <Loader isLoading={isLoading} />
}
if (isError) {
return <Error />
}
const filteredBooks = data.filter(
({ author, title }: { author: string, title: string }) =>
author.toLowerCase().startsWith(searchInputValue.toLowerCase()) ||
title.toLowerCase().startsWith(searchInputValue.toLowerCase())
)
const booksPerPage = 6;
const pagesVisited = pageNumber * booksPerPage;
const displayBooks = filteredBooks.length > 0 ? filteredBooks.slice(pagesVisited, pagesVisited + booksPerPage).map((book: bookType) => {
return (
<SingleBook key={book.id} book={book} />
)
}) : <p>The library does not contain such books. Check spelling or try another book</p>
const pageCount = Math.ceil(filteredBooks.length / booksPerPage);
const changePage = ({ selected }: { selected: number }): void => {
setPageNumber(selected)
}
return (
<BookContainer>
<BookContent>
<Navbar />
{displayBooks}
</BookContent>
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
pageCount={pageCount}
onPageChange={changePage}
containerClassName={'pagination'}
activeClassName={'active'}
/>
</BookContainer>
)
}
const BookContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
height: 100vh;
padding: 0 20px;
`
const BookContent = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
width: 1200px;
`
In data we keep array of objects with books:
Single object looks like that:
{
"id": 458,
"title": "Some crazy title",
"author": "Some crazy author",
"cover_url": "/static/cover/book/458.jpg",
"pages": 300,
"price": 3300,
"currency": "EUR"
},
SearchInputValue is a text from another input component which is used to filtered array of books depend on text what user will type in input.
filteredBooks - array of filtered books depends on searchInputValue
Rest of the code is to display pagination from react-paginate library
The problem is: If we type something in input, the filter works only on the first page of pagination. On the 2nd page if we type something what exist, displayBooks does not show. I know the problem is with slice, but I to be honest I dont know how I can solve this.
Solution 1:[1]
Here the problem is when you are at different page and you start searching so your number of pages also get reduced, let say you are at 3rd page and then after searching there is only 2 pages to show and since you are still at 3rd page so you see nothing.
One Solution could be set the active page number to 0 each time when you search or type in the search bar.
Another solution could be select the last page if in case available number of pages (after search) is less then selected page (before search).
Sharing code for the first solution (selecting firsts page, when user start searching). I have extended and modified your code.
import React, { useState } from "react";
import ReactPaginate from "react-paginate";
import styled from "styled-components";
const data = [
{
id: 458,
title: "Do Epic Shit",
author: "Some crazy author",
},
{
id: 459,
title: "Rudest book ever",
author: "Some crazy author",
},
{
id: 460,
title: "Lost Girlfriend",
author: "Some crazy author",
},
{
id: 461,
title: "rude uncle",
author: "Some crazy author",
},
{
id: 462,
title: "money story",
author: "Some crazy author",
},
{
id: 463,
title: "love",
author: "Some crazy author",
},
];
const Test = () => {
const [searchText, SetSeatchText] = useState("");
const [pageNumber, setPageNumber] = useState(0);
const booksPerPage = 2;
const pagesVisited = pageNumber * booksPerPage;
const filteredBooks = data.filter(
({ author, title }) =>
author.toLowerCase().startsWith(searchText.toLowerCase()) ||
title.toLowerCase().startsWith(searchText.toLowerCase())
);
const displayBooks =
filteredBooks.length > 0 ? (
filteredBooks
.slice(pagesVisited, pagesVisited + booksPerPage)
.map((book) => {
return (
<div key={book.id} book={book}>
{book.title}
</div>
);
})
) : (
<p>
The library does not contain such books. Check spelling or try another
book
</p>
);
const pageCount = Math.ceil(filteredBooks.length / booksPerPage);
const changePage = ({ selected }) => {
setPageNumber(selected);
};
return (
<BookContainer>
<input
type="text"
value={searchText}
onChange={(e) => {
SetSeatchText(e.target.value);
setPageNumber(0);
}}
/>
<BookContent>
<div>Navbar</div>
</BookContent>
{displayBooks}
<ReactPaginate
previousLabel={"Previous"}
nextLabel={"Next"}
pageCount={pageCount}
onPageChange={changePage}
containerClassName={"pagination"}
activeClassName={"active"}
/>
</BookContainer>
);
};
const BookContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
height: 100vh;
padding: 0 20px;
`;
const BookContent = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
width: 1200px;
`;
export default Test;
Solution 2:[2]
One approach would be to import DynamoDB table into CloudFormation using CloudFormation import feature, and then retroactively model it in CDK, making sure that logical ID of resource matched the one in CloudFormation after import. You can overwrite logical ID in CDK using overrideLogicalId method of the CfnResourse construct.
This way your table remains in place and no migration is needed.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Frontend Team |
| Solution 2 | Tofig Hasanov |
