React:创建自定义分页钩子
本文将实现一个通用的、可复用的分页机制。我们将通过实现自定义钩子来实现这一点。
什么是定制钩?
引用React 官方文档:
自定义 Hook 是一个 JavaScript 函数,其名称以“use”开头,并且可以调用其他 Hook。
本质上,自定义 Hook 是一个 React 函数式组件,它会导出 props,其中至少一个 prop 以 `@Hook` 关键字为前缀use。` use@Hook` prop 的作用类似于构造函数:它定义了函数式组件所需的初始值。其他 props 可以是函数或 Hook 的状态值——您可以自行决定要公开哪些内容。
要求
分页是将项目列表分成不同的“页面”。它允许用户在页面之间浏览,既可以跳转到下一页,也可以跳转到上一页,或者直接跳转到集合中的任意页面。因此,我们确定了以下需求:
- 应该允许跳转到上一页或下一页
- 应该允许跳转到集合中的任何页面。
- 应返回与当前页面对应的数据
对于分页自定义钩子,这意味着需要满足以下要求:
- 应该可以配置每页显示的项目数量
- 应该有状态以保持当前页面
步骤 1:配置项目数量和当前页面
让我们开始实现自定义钩子。首先,我们定义usePagination构造函数。它接收数据和每页显示的项目数。我们还实现了一个有状态变量currentPage。
1 import React, {useState} from 'react';
2
3 function usePagination(data, itemsPerPage) {
4 const [currentPage, setCurrentPage] = useState(1);
5 const maxPage = Math.ceil(data.length / itemsPerPage);
6 }
7
8 export default usePagination;
更详细地说:
- 在第 3 行,我们实现了该
usePagination函数,并传递了参数data和itemsPerPage currentPage在第 4 行,我们使用useState内置钩子1定义状态变量。- 在第 5 行,我们设置了一个
maxPage变量,该变量定义了我们可以显示的页面数量的上限。 - 在第 8 行,我们导出
usePagination函数
步骤 2:增加、减少并转到任意页面
这些需求构成了我们钩子函数的核心功能。我们将把它们实现为函数并导出。因此,我们需要确保其值currentPage始终在 1 到指定maxPage值之间。
让我们开始编写代码:
1 function next() {
2 setCurrentPage((currentPage) => Math.min(currentPage + 1, maxPage));
3 }
4
5 function prev() {
6 setCurrentPage((currentPage) => Math.max(currentPage - 1, 1));
7 }
8
9 function jump(page) {
10 const pageNumber = Math.max(1, page)
11 setCurrentPage((currentPage) => Math.min(pageNumber, maxPage));
12 }
- 第 1 行:该
next函数将值加currentPage1,但不会超过maxPage - 第 5 行:该
prev函数将值减currentPage1,但不会低于 1。 - 第 9 行:该
jump函数确保始终currentPage在两个限制范围内。
步骤 3:返回当前页面数据
最后一步是实现只显示当前页面的数据。
1 function currentData() {
2 const begin = (currentPage - 1) * itemsPerPage;
3 const end = begin + itemsPerPage;
4 return data.slice(begin, end);
5 }
该变量data保存分页组件的所有项。我们从中选择itemsPerPage,从值开始,currentPage - 1因为数组索引从 0 开始0。
分页钩子:完整组件
以下是完整的组件:
1 import React, { useState } from "react";
2
3 function usePagination(data, itemsPerPage) {
4 const [currentPage, setCurrentPage] = useState(1);
5 const maxPage = Math.ceil(data.length / itemsPerPage);
6
7 function currentData() {
8 const begin = (currentPage - 1) * itemsPerPage;
9 const end = begin + itemsPerPage;
10 return data.slice(begin, end);
11 }
12
13 function next() {
14 setCurrentPage((currentPage) => Math.min(currentPage + 1, maxPage));
15 }
16
17 function prev() {
18 setCurrentPage((currentPage) => Math.max(currentPage - 1, 1));
19 }
20
21 function jump(page) {
22 const pageNumber = Math.max(1, page);
23 setCurrentPage((currentPage) => Math.min(pageNumber, maxPage));
24 }
25
26 return { next, prev, jump, currentData, currentPage, maxPage };
27 }
28
29 export default usePagination;
结论
本文介绍了如何实现自定义 React Hook。Hook 会将其函数和部分状态暴露给调用者。调用者调用 Hook 中的函数,并决定如何渲染结果和分页。自定义 Hook 功能强大,有助于定义可复用的功能。
-
是的,你可以在其他钩子中复用内置/自定义钩子 。↩