Использование React Hook для поиска и фильтрации элементов из Api с разбивкой на страницы - PullRequest
0 голосов
/ 14 июля 2020

Используя перехватчики реакции, я вызываю api и отображаю элементы в компоненте приложения, вызывая функциональный компонент книги и разбивки на страницы. У меня есть компонент поиска, расположенный вверху в возврате приложения. Может ли кто-нибудь помочь: при нажатии кнопки поиска после вставки названия книги должны отображаться книги с похожими названиями

const SearchBooks =() => {
    return (
        <InputGroup>
            <FormControl
                type="text"
                placeholder="Search books"
                onChange={e => (e.target.value)}
            />
            <InputGroup.Append>
                <Button >
                    Search
                </Button>
            </InputGroup.Append>
        </InputGroup>
    );
}

const Book = ({books, loading}) => {
    if(loading) {
        return <h2>Loading...</h2>
    }  
    return (books.map((book) =>
        <ListGroup className="text-primary" key={book.id}>
            <ListGroup.Item>
                <h4>{book.book_title}</h4>
                <li>Author : {book.book_author}</li>
                <li>Publication Year : {book.book_publication_year}</li>
                <li>Publication Country : {book.book_publication_country}</li>
                <li>Publication City : {book.book_publication_city}</li>
                <li >Pages : {book.book_pages}</li>
            </ListGroup.Item>
        </ListGroup>
    ));
}    
const App = () => {   
    const [books, setBooks] = useState([]);
    const [loading, setLoading] = useState(false);
    const [currentPage, setCurrentPage] = useState(1);
    const [booksPerPage] = useState(2);
    const [search, setSearch] = useState('');

    useEffect(() => {
        const fetchBooks = async () => {
            setLoading(true);
            const res = await axios.post("http://nyx.vima.ekt.gr:3000/api/books");
            setBooks(res.data.books);
            setLoading(false);
        };

        fetchBooks();
    }, []);

    // Get current books
    const indexOfLastBook = currentPage * booksPerPage;
    const indexOfFirstBook = indexOfLastBook - booksPerPage;
    const currentPosts = books.slice(indexOfFirstBook, indexOfLastBook);

    // Change page
    const paginate = pageNumber => setCurrentPage(pageNumber);

    return (
        <div className='container mt-5'>
            <SearchBook/>
            <Book books={currentPosts} loading={loading}/>
            <Pagination
                booksPerPage={booksPerPage}
                totalBooks={books.length}
                paginate={paginate}
            />
        </div>
    );
}

import React from 'react';
const Pagination = ({ booksPerPage, totalBooks, paginate }) => {
    const pageNumbers = [];

    for (let i = 1; i <= Math.ceil(totalBooks / booksPerPage); i++) {
        pageNumbers.push(i);
    }

    return (
        <nav className="justify-content-center">
            <ul className='pagination'>
                {pageNumbers.map(number => (
                    <li key={number} className='page-item'>
                        <a onClick={() => paginate(number)} href='!#' className='page-link'>
                            {number}
                        </a>
                    </li>
                ))}
            </ul>
        </nav>
    );
};

1 Ответ

0 голосов
/ 14 июля 2020
const currentPosts = books.fliter(book => book.title.includes(keyword)).slice(indexOfFirstBook, indexOfLastBook);

, и вам также следует пересчитать разбивку на страницы и сбросить номер страницы, чтобы пользователи могли переходить на страницы, если результат поиска слишком длинный.

вы также можете использовать useMemo хуки для его оптимизации , поэтому он не будет фильтровать массив снова при каждом повторном рендеринге.

const currentPosts = useMemo(() => books.filter(...).slice(...), [books, keyword]);
...