我正在为 React 项目构建分页。当我单击上一页或下一页按钮时,分页本身确实可以工作,但我有两个问题,我无法弄清楚。
我还在 Chrome 开发工具中收到此警告: 在简单的会话历史记录上下文中使用history.pushState,该上下文仅维护一个会话历史记录条目。看来这个警告说明了问题,但是如何保存多条历史记录呢?
代码:
let [currentPage, setCurrentPage] = useState(getCurrentPage());
let [pagesCount, setPagesCount] = useState(0);
let [itemsCount, setItemsCount] = useState(0);
let [productData, UpdateProductData] = useState([]);
const [searchParams, setSearchParams] = useSearchParams();
//On init
useEffect(() => {
getCurrentPage();
setSearchParams({ p: `${currentPage}` });
calcPagesCount();
getData();
}, []);
//Updates screen if query is changed by browser back button or manually changing query in url bar
useEffect(() => {
let CurrentPageFromQuery: number;
CurrentPageFromQuery = Number(location.search.replace(/\D/g, ""));
setCurrentPage(CurrentPageFromQuery);
saveCurrentPage();
getData();
}, [searchParams]);
//Updates query if next/prev page buttons are clicked
useEffect(() => {
saveCurrentPage();
getData();
setSearchParams({ p: `${currentPage}` });
}, [currentPage]);
function prevPage() {
if (currentPage !== 1) {
getCurrentPage();
setCurrentPage(currentPage - 1);
saveCurrentPage();
}
}
function nextPage() {
if (currentPage !== pagesCount) {
getCurrentPage();
setCurrentPage(currentPage + 1);
saveCurrentPage();
}
}
function saveCurrentPage() {
sessionStorage.setItem("current page", String(currentPage));
}
function getCurrentPage(): number {
return Number(sessionStorage.getItem("current page") || 1);
}
async function calcPagesCount() {
const api_url = `https://******&per_page=99`;
const req = await fetch(api_url);
const products = await req.json();
setItemsCount(products.length);
setPagesCount(Math.floor(products.length / 9));
}
async function getData() {
const api_url = `https://******&per_page=9&page=${currentPage}`;
const req = await fetch(api_url);
const products = await req.json();
UpdateProductData(products);
}
对于您所在的页面,您应该只有单一的事实来源。在这里,您使用 URL 搜索参数和本地
currentPage
状态、和 ,然后在其之上使用 sessionStorage。我认为你也有太多的副作用和重载的函数/处理程序/回调。
我怀疑您不需要
currentPage
状态,您可以读取和更新 p
URLSearchParameter 并与 sessionStorage 同步。
建议更改:
p
并且存在存储的会话值时,才从 sessionStorage 更新 p
搜索参数。prevPage
/nextPage
仅更新 URL 搜索参数示例:
const [searchParams, setSearchParams] = useSearchParams();
const [pagesCount, setPagesCount] = useState(0);
const [itemsCount, setItemsCount] = useState(0);
const [productData, UpdateProductData] = useState([]);
// Read current page from search params, fallback to storage
const currentPage = Number(searchParams.get("p")) ?? getCurrentPage();
// Fetch data for the current page
useEffect(() => {
getData(currentPage);
calcPagesCount();
saveCurrentPage(currentPage);
}, [currentPage]);
function prevPage() {
setSearchParams(searchParams => {
const p = Number(searchParams.get("p")) || 1;
searchParams.set("p", Math.max(1, p - 1));
return searchParams;
});
}
function nextPage() {
setSearchParams(searchParams => {
const p = Number(searchParams.get("p")) || 1;
searchParams.set("p", Math.min(p + 1, pagesCount));
return searchParams;
});
}
function saveCurrentPage(currentPage: number) {
sessionStorage.setItem("current page", String(currentPage));
}
function getCurrentPage(): number {
return Number(sessionStorage.getItem("current page") || 1);
}
async function getData(currentPage: number) {
const api_url = `https://******&per_page=9&page=${currentPage}`;
const req = await fetch(api_url);
const products = await req.json();
UpdateProductData(products);
}