First I'm not sure if the functionality of my filter/search bar are correct.
Here are my concern, we have the words 'dolor' and 'dolorum' in the items of 25pages.
You can view it here.
Try to search the word "dolor" in the searchbar, the 25pages pagination is now 18pages. Then click the third pagination links and update your search to 'dolorum' in the searchbar, see the message says 'No Posts Found!
' and the pagination is now 2pages. But we have 'dolorum' content in the items but it is only up to two pages of the pagination, and I think that is the reason why I got an error of 'No Posts Found!
', because I clicked the third pagination items.
Is my code/functionality right? Is there any suggestions to avoid that bug in my code? maybe update the pagination/content items everytime I search?
Below is my code and to better understand here is the complete sandbox code https://codesandbox.io/. Full view here codesandbox. It's free to fork it!
Movielist.js
import { React, useState, useEffect } from "react";
import MovieListPagination from "./MovieListPagination";
import SearchBar from "./SearchBar";
const MovieList = () => {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
const [searchResults, setSearchResults] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((res) => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
setSearchResults(result);
//console.log(result);
},
(error) => {
setIsLoaded(true);
setError(error);
}
);
}, []);
if (error) {
return <div className="p-3">Error: {error.message}</div>;
} else if (!isLoaded) {
return <div className="p-3">Loading...</div>;
} else {
return (
<>
<SearchBar items={items} setSearchResults={setSearchResults} />
<MovieListPagination dataProps={searchResults} itemsPerPage={4} />
</>
);
}
};
export default MovieList;
MovielistPagination.js
import { React, useState } from "react";
import { Row, Alert } from "react-bootstrap";
import ReactPaginate from "react-paginate";
import MovieListItems from "./MovieListItems";
const MovieListPagination = ({ itemsPerPage, dataProps }) => {
const [itemOffset, setItemOffset] = useState(0);
const endOffset = itemOffset + itemsPerPage;
const currentItems = dataProps.slice(itemOffset, endOffset);
const pageCount = Math.ceil(dataProps.length / itemsPerPage);
const handlePageClick = (event) => {
const newOffset = (event.selected * itemsPerPage) % dataProps.length;
setItemOffset(newOffset);
};
const results = currentItems.map((item) => (
<MovieListItems key={item.id} items={item} />
));
const content = results?.length ? (
results
) : (
<Alert variant="primary">No Posts Found!</Alert>
);
return (
<>
<Row className="justify-content-center">{content}</Row>
<ReactPaginate
breakLabel="..."
nextLabel="›"
onPageChange={handlePageClick}
pageRangeDisplayed={3}
marginPagesDisplayed={1}
pageCount={pageCount}
previousLabel="‹"
renderOnZeroPageCount={null}
containerClassName="justify-content-center pagination"
previousClassName="page-item"
previousLinkClassName="page-link"
nextClassName="page-item"
nextLinkClassName="page-link"
pageClassName="page-item"
pageLinkClassName="page-link"
breakClassName="page-item"
breakLinkClassName="page-link"
activeClassName="active"
disabledClassName="disabled"
/>
</>
);
};
export default MovieListPagination;
SearchBar.js
import { Form, Button } from "react-bootstrap";
const SearchBar = ({ items, setSearchResults }) => {
const handleSubmit = (e) => e.preventDefault();
const handleSearchChange = (e) => {
if (!e.target.value) return setSearchResults(items);
const resultsArray = items.filter(
(item) =>
item.title.includes(e.target.value.toLowerCase()) ||
item.body.includes(e.target.value.toLowerCase())
);
setSearchResults(resultsArray);
};
return (
<>
<Form onSubmit={handleSubmit}>
<Form.Group className="my-3">
<Form.Control
type="text"
id="search"
placeholder="Search here..."
onChange={handleSearchChange}
/>
</Form.Group>
<Button className="d-none" variant="primary" type="submit">
Search
</Button>
</Form>
</>
);
};
export default SearchBar;