在 React 中实现原生分页
React 是一个用于构建现代单页应用程序的 JavaScript 库。SPA 以其速度和卓越的用户体验而闻名。但是,实现提供出色 UX 的功能需要付出很多努力。
分页是这些功能之一,对于一些包含大量数据的应用程序来说是必不可少的。
无论你的应用程序有多复杂,分页都可以让你确保网站上的页面没有信息过多。分页将使用户能够轻松访问内容。
例如,如果你的博客有很多帖子,用户可能需要一段时间才能找到几年前的特定帖子。当有分页功能并且每个页面都有特定数量的帖子时,这更容易做到。
我们可以在后端或前端进行分页。本文旨在讨论在 React 中原生实现分页功能。
在 React 中实现原生分页
要在 React 中实现原生解决方案,我们需要使用状态。例如,我们需要一个状态变量 currentPage
来存储一个整数来指定应该显示哪些项目批次。
我们还将有一个状态变量来存储每个页面上显示的项目数。我们可以拥有固定数量的项目,而不是将这些信息存储在变量中。
但是,如果我们想改变每页显示的项目数或者让用户改变,最好把它保存在 state 中。最后,我们应该有一个状态变量来存储要显示的项目。
我们来看一个实际的例子:
import "./styles.css";
import { useState } from "react";
export default function App() {
const [items, setItems] = useState([
"item 1",
"item 2",
"item 3",
"item 4",
"item 5",
"item 6",
"item 7",
"item 8",
"item 9",
"item 10"
]);
const [currentPage, setCurrentPage] = useState(1);
const [todosPerPage, setTodosPerPage] = useState(3);
return (
<div className="App">
</div>
);
}
在此代码示例中,我们导入 useState
挂钩并设置三个状态变量:
items
来存储我们需要显示的项目,currentPage
存储需要显示的页面的整数值(默认为 1),以及todosPerPage
存储每页上的项目数。
现在,让我们在代码中添加一点逻辑。
由于我们在每个页面上显示一定数量的项目,并且用户可以在页面之间切换,因此我们需要弄清楚需要显示哪些项目。我们有十个项目,每页有三个项目,所以我们将有四页。
第一页将显示第一个、第二个和第三个项目,依此类推。我们可以硬编码应该为每个页面显示哪些项目,但是开发一个可以处理任意数量项目的系统要明智得多。
我们来看看逻辑:
const [currentPage, setCurrentPage] = useState(1);
const [todosPerPage, setTodosPerPage] = useState(3);
const lastTodoInView = currentPage * todosPerPage;
const firstTodoInView = lastTodoInView - todosPerPage;
lastTodoInView
和 firstTodoinView
这两个变量表示数组中的索引,这应该是在特定页面上显示项目的边界
。例如,对于第一页,假设 todosPerPage
设置为三,边界将是:
最后一个:1 (currentPage) * 3 (todosPerPage) = 3
第一个:3 (lastTodoInView) - 3 (todosPerPage) = 0
请注意,在 JavaScript 中,数组的第一项索引为 0,因此要显示在第一页上的项将具有 0、1 和 2 索引,直到它们达到 3。最后一个数组索引不包含在内,因为如何 .slice()
方法是设计好的,所以我们的页面不会包含索引 3 上的项目。
接下来,我们可以使用 .slice()
方法来提取每个页面上显示的特定值。
const todosForDisplay = items.slice(firstTodoInView, lastTodoInView);
这个方法有两个参数,数组项的开始和结束索引。起始索引是包含的,这意味着如果第一个参数为 0,则一旦执行该方法,新返回的数组将包含第一项。
结束索引不包含在内,这意味着如果第二个参数为 3,则返回的数组将在索引 2 处停止。
然后,我们可以创建一个变量来存储从切片数组生成的所有 JSX 元素。
const renderItems = todosForDisplay.map((todo, index) => {
return <li key={index}>{todo}</li>;
});
建议将 key
属性设置为唯一值,以便 React 可以在内部跟踪各个节点。
稍后,我们将添加代码以允许用户更改 currentPage
变量,或者简单地说,从一个页面转到另一个页面。我们还可以添加更新每个页面上显示的项目数量的功能,一切都会正常工作。
接下来,我们必须生成一个页码数组。随着数组中项目数量的增加,页数也应该增加。
例如,目前,我们的数组有 10 个项目和 4 个页面来显示它们。如果我们再添加 5 个项目,我们需要计算要显示它们的页面数。
以下是计算显示所有项目所需的页数的逻辑:
const pageNumbers = [];
for (let n = 1; n <= Math.ceil(items.length / todosPerPage); n++) {
pageNumbers.push(n);
}
在这里,我们生成了一个简单的 for
循环。我们从初始值 1 开始,并将其添加到 pageNumbers
数组中。
我们添加越来越多的页面,直到有足够的页面来显示每个项目。然后我们必须生成要在应用程序中显示的实际页码。
为此,我们将在 pageNumbers
数组上使用 .map()
方法。让我们看一下代码:
const renderPageNumbers = pageNumbers.map((number, index) => {
return <li key={index}>{number}</li>;
});
这将生成与页码对应的所有 JSX 元素。我们必须创建一个事件处理程序以允许用户从一个页面移动。
这很容易实现,因为 useState()
钩子提供了一个简单的更新函数来更新值。我们要处理点击事件,事件处理函数可以很简单:
const renderPageNumbers = pageNumbers.map((number, index) => {
return <li onClick={() => setCurrentPage(number)} key={index}>
{number}
</li>
});
最后,我们简单的分页系统就完成了。你可以查看 CodeSandbox 上的演示,了解所有内容如何组合在一起。
Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.
LinkedIn