下面是分页组件:
import React from 'react';
import classnames from 'classnames';
import { usePagination, DOTS } from './usePagination';
import './pagination.css';
const Pagination = props => {
const {
onPageChange,
totalCount,
siblingCount = 1,
currentPage,
pageSize,
className
} = props;
const paginationRange = usePagination({
currentPage,
totalCount,
siblingCount,
pageSize
});
if (currentPage === 0 || paginationRange.length < 2) {
return null;
}
const onNext = () => {
onPageChange(currentPage + 1);
};
const onPrevious = () => {
onPageChange(currentPage - 1);
};
let lastPage = paginationRange[paginationRange.length - 1];
return (
<ul
className={classnames('pagination-container', { [className]: className })}
>
<li
className={classnames('pagination-item', {
disabled: currentPage === 1
})}
onClick={onPrevious}
>
<div className="arrow left" />
</li>
{paginationRange.map(pageNumber => {
if (pageNumber === DOTS) {
return <li className="pagination-item dots">…</li>;
}
return (
<li
className={classnames('pagination-item', {
selected: pageNumber === currentPage
})}
onClick={() => onPageChange(pageNumber)}
>
{pageNumber}
</li>
);
})}
<li
className={classnames('pagination-item', {
disabled: currentPage === lastPage
})}
onClick={onNext}
>
<div className="arrow right" />
</li>
</ul>
);
};
export default Pagination;
它被集成在review的页面中,如下所示:
import React, { useEffect, useState, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import LoadingSpinner from "../Commons/LoadingSpinner";
import FeedCheckFilter from "../Commons/Filters/Filter";
import { getLimitedReviews, updateFilters } from '../../services/FiltersService';
import Review from './Review';
import Pagination from "../Commons/Pagination/Pagination";
let PageSize = 10;
const initialState = {
limit: 10,
offset: 0,
reviews: [],
count: 0
}
export default function Reviews() {
const dispatch = useDispatch()
const token = useSelector((state) => state.user.profile.token)
const username = useSelector((state) => state.user.profile.auth)
const reviews = useSelector((state) => state.reviewsData.reviews)
const [currentPage, setCurrentPage] = useState(1);
const [reviewsState, setReviewsState] = useState(initialState)
...
const loadData = async (queryUrl = filters.url, limit=10, offset=0) => {
setIsLoading(true)
// let queryUrl = filters.url;
if (limit || offset) {
let action = await getLimitedReviews(token, username, queryUrl || defaultQueryUrl, limit, offset)
setReviewsState(action.payload)
dispatch(action)
}
setIsLoading(false)
}
const currentReviewsData = useMemo(() => {
const firstPageIndex = (currentPage - 1) * PageSize;
const lastPageIndex = firstPageIndex + PageSize;
loadData(filters.url, lastPageIndex, firstPageIndex)
if (reviews) {
return reviews
} else {
return []
}
}, [currentPage]);
...
useEffect(() => {
loadData();
}, [])
...
return (
<div>
<h1>Reviews</h1>
{isLoading ? <LoadingSpinner /> :
<>
...
{currentReviewsData.map(item => {
return (<Review key={item.id} review={item} />)
})}
<Pagination
className="pagination-bar"
currentPage={currentPage}
totalCount={reviewsState.count}
pageSize={PageSize}
onPageChange={page => setCurrentPage(page)}
/>
</>
}
</div>
)
}
问题是,当我按下按钮从第1页转到第2页时,评论只有在渲染后才会更新。因此,该页仍保留前一页的评论。例如,如果我在第5页,我按下按钮转到第6页。在第6页,我看到第5页的评论,现在如果我转到第7页,例如,然后我会看到第6页的评论。
这里我有一个钩子,我正在使用分页,但我认为问题不在这里:
import React from 'react';
import { useMemo } from 'react';
export const DOTS = '...';
const range = (start, end) => {
let length = end - start + 1;
return Array.from({ length }, (_, idx) => idx + start);
};
export const usePagination = ({
totalCount,
pageSize,
siblingCount = 1,
currentPage
}) => {
const paginationRange = useMemo(() => {
const totalPageCount = Math.ceil(totalCount / pageSize);
// Pages count is determined as siblingCount + firstPage + lastPage + currentPage + 2*DOTS
const totalPageNumbers = siblingCount + 5;
/*
If the number of pages is less than the page numbers we want to show in our
paginationComponent, we return the range [1..totalPageCount]
*/
if (totalPageNumbers >= totalPageCount) {
return range(1, totalPageCount);
}
const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
const rightSiblingIndex = Math.min(
currentPage + siblingCount,
totalPageCount
);
/*
We do not want to show dots if there is only one position left
after/before the left/right page count as that would lead to a change if our Pagination
component size which we do not want
*/
const shouldShowLeftDots = leftSiblingIndex > 2;
const shouldShowRightDots = rightSiblingIndex < totalPageCount - 2;
const firstPageIndex = 1;
const lastPageIndex = totalPageCount;
if (!shouldShowLeftDots && shouldShowRightDots) {
let leftItemCount = 3 + 2 * siblingCount;
let leftRange = range(1, leftItemCount);
return [...leftRange, DOTS, totalPageCount];
}
if (shouldShowLeftDots && !shouldShowRightDots) {
let rightItemCount = 3 + 2 * siblingCount;
let rightRange = range(
totalPageCount - rightItemCount + 1,
totalPageCount
);
return [firstPageIndex, DOTS, ...rightRange];
}
if (shouldShowLeftDots && shouldShowRightDots) {
let middleRange = range(leftSiblingIndex, rightSiblingIndex);
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex];
}
}, [totalCount, pageSize, siblingCount, currentPage]);
return paginationRange;
};
1条答案
按热度按时间wrrgggsh1#
我认为你的备忘录不是在等待结果,所以你总是得到前一页的结果。
在我看来,我不认为你应该使用备忘录的
currentReviewsData
。试试这个: