使用useState、Material-UI与自定义hook实现搜索结果分页的问题求助
问题根因
- 存在冗余分页状态:你同时在
Main组件和usePagination自定义Hook中维护了两个独立的页码状态,两者没有同步机制。就算你在搜索更新时修改了组件内的page,Hook内部的currentPage仍停留在旧数值,分页数据是基于Hook内的状态计算的,自然不会加载第一页内容。 - 搜索条件变更无页码重置逻辑:当用户输入新搜索词,过滤后的
filteredReviews列表发生变化时,没有触发Hook内的页码重置逻辑。
解决方案
第一步:修改usePagination自定义Hook
新增useEffect监听数据源变化,数据源更新时自动重置页码到1:
import { useState, useEffect } from "react"; export default function usePagination(allReviews, perPage) { const [currentPage, setCurrentPage] = useState(1); const maxPage = Math.ceil(allReviews.length / perPage); // 新增:数据源变化时自动回到第1页 useEffect(() => { setCurrentPage(1); }, [allReviews]) function pageData() { const start = (currentPage - 1) * perPage; const end = start + perPage return allReviews.slice(start, end); } function jumpPage(page) { const pageNumber = Math.max(1, page); setCurrentPage((currentPage) => Math.min(pageNumber, maxPage)); } return { jumpPage, pageData, currentPage, maxPage } }
第二步:修改Main组件,删除冗余状态
移除组件内重复维护的page状态,直接使用Hook返回的currentPage即可:
import React, { useState } from "react"; import Pagination from "@material-ui/core/Pagination"; import usePagination from "./usePagination.js"; export default function Main({reviews, web3}) { const [search, setSearch] = useState(""); // 移除冗余的[page, setPage]状态 const updateSearch = (event) => { setSearch(event.target.value.substr(0, 20)); } const filteredReviews = reviews.filter( (review) => { return review.restaurantName.indexOf(web3.utils.toHex(search)) !== -1; }); const paginatedReviews = usePagination(filteredReviews, 2); const handleChange = (e, p) => { paginatedReviews.jumpPage(p); } return ( <div className="container-fluid mt-5" style={{ minHeight: "100vh" }}> <div className="row"> <main role="main" className="col-lg-12 ml-auto mr-auto" style={{ maxWidth: '500px' }}> <div className="content mr-auto ml-auto"> <input type="text" className="form-control" value={search} onChange={updateSearch} /> {filteredReviews.length > 0 ? paginatedReviews.pageData().map((review, key) => { return ( <> <div key={key}> {/* 搜索结果项渲染逻辑 */} </div> </> ) }) : null} {filteredReviews.length > 1 ? <Pagination count={paginatedReviews.maxPage} page={paginatedReviews.currentPage} onChange={handleChange} /> : null } </div> </main> </div> </div> ); }
修改完成后,用户输入新搜索词时,过滤后的列表变更会触发Hook自动重置页码到第一页,无需手动操作分页栏即可正常加载新搜索的第一页结果。
内容的提问来源于stack exchange,提问作者A-PSquestions
相关产品推荐
相关产品推荐

