0%

react-ant-design-component-table-4

介绍

这篇文章我们继续讲解Ant Design中的Table组件,今天我们来看看如何为Table组件添加分页功能。随着项目的进行,数据量会变得越来越大,一页不可能显示所有的数据,所以分页功能就非常必要了。

为Table组件添加分页功能

为了实现分页,我们首先模拟一些数据,假设后端API返回100条数据,我们改造一下fetchUsers这个方法,动态生成100条User数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export async function fetchUsers() {
const users: User[] = Array.from({ length: 100 }, (_, index) => ({
id: index + 1,
name: `User${index + 1}`,
email: `user${index + 1}@gmail.com`,
phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`,
}));

return new Promise<{ data: User[] }>((resolve) => {
setTimeout(() => {
resolve({ data: users });
}, 1000); // 1秒后返回数据
});
}

现在运行程序,发现分页功能已经自动启用了,这是因为Ant Design的Table组件默认会启用分页功能。但是这个分页实际上是纯前端的分页,也就是说,Table组件会把所有数据都加载到前端,然后自己在前端进行分页,这样做的缺点是如果数据量非常大,前端加载时间会很长,用户体验会很差。

所以,真正的分页一定需要后端api的支持,前端只需要传递当前页码和每页条数给后端,后端返回对应页码的数据即可。我们改造一下fetchUsers方法,模拟后端分页的api。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { User } from "./User";

export async function fetchUsers(pageNumber: number, pageSize: number = 10): Promise<{ data: User[] }> {
// 动态生成100条数据
const users: User[] = Array.from({ length: 100 }, (_, index) => ({
id: index + 1,
name: `User${index + 1}`,
email: `user${index + 1}@gmail.com`,
phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`,
}));

// 获取分页对应的数据
const pageData = users.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);

// 返回分页数据
return new Promise<{ data: User[] }>((resolve) => {
setTimeout(() => {
resolve({ data: pageData });
}, 1000); // 1秒后返回数据
});
}

然后改造一下getUsers方法,传递页码和每页条数给fetchUsers方法。

1
2
3
4
5
6
7
8
9
10
11
const getUsers = async (pageNumber: number, pageSize?: number) => {
try {
setLoading(true);
const res = await fetchUsers(pageNumber, pageSize);
setTableData(res.data);
} catch (error) {
console.error('Error fetching users:', error);
} finally {
setLoading(false);
}
};

接下来在useEffect中调用getUsers方法时,传递页码1。

1
2
3
useEffect(() => {
getUsers(1); //
}, []);

这时候,你会发现Table组件右下角没有分页了,只显示了一个页码1,这是因为我们只返回了一页数据,要开启分页功能必须返回一个total参数告知Table组件数据的总数。

我们在fetchUsers方法中添加一个total参数,表示数据的总数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { User } from "./User";

// 定义分页查询用户的响应类型
export interface FetchUsersResponse {
data: User[];
total: number;
}

export async function fetchUsers(pageNumber: number, pageSize: number = 10): Promise<FetchUsersResponse> {
// 动态生成100条数据
const users: User[] = Array.from({ length: 100 }, (_, index) => ({
id: index + 1,
name: `User${index + 1}`,
email: `user${index + 1}@gmail.com`,
phone: `130${Math.floor(10000000 + Math.random() * 90000000)}`,
}));

// 获取分页对应的数据
const pageData = users.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);

// 返回分页数据和总数
return new Promise<FetchUsersResponse>((resolve) => {
setTimeout(() => {
const response: FetchUsersResponse = { data: pageData, total: users.length };
resolve(response);
}, 1000); // 1秒后返回数据
});
}

在Users页面,我们需要定一个state来保存total

1
const [total, setTotal] = useState(0); // 总数据条数

然后在获取数据时,设置total

1
2
3
4
5
6
7
8
9
const getUsers = async (pageNumber: number, pageSize?: number) => {
try {
setLoading(true);
const res = await fetchUsers(pageNumber, pageSize);
setTableData(res.data);
setTotal(res.total); // 设置总数据条数
}
// ...
};

最后,在Table组件中传递total属性,并响应onChange函数,在用户切换页面时,获取对应的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
<Table
loading={loading}
dataSource={tableData}
columns={columns}
rowKey={'id'}
pagination={{
pageSize: 10,
total: total,
onChange: (page) => {
getUsers(page);
},
}}
/>

此时重新运行程序,然后点击不同的页码,你会发现数据会根据页码变化而变化,这样分页功能就实现了。但是当你改变每页显示的条数时,你会发现数据并没有变化,这是因为我们在onChange函数中没有传递每页条数,而是将每页条数固定为10条了,我们需要改造一下onChange函数,传递每页条数。

我们可以添加一个新函数来响应Table组件的onChange事件。

1
2
3
4
const onPageChange = (pageNumber: number, pageSize: number) => {
setPageNumber(pageNumber);
setPageSize(pageSize);
};

然后将pageNumberpageSize保存到state中。

1
2
const [pageNumber, setPageNumber] = useState(1); // 当前页码
const [pageSize, setPageSize] = useState(10); // 每页条数

并更新useEffect,将pageNumberpageSize作为依赖变量,这样当他们变化时,重新获取数据。

1
2
3
useEffect(() => {
getUsers(pageNumber, pageSize);
}, [pageNumber, pageSize]);

最后在Table组件中传递onPageChange函数。

1
2
3
4
5
6
7
8
9
10
<Table
loading={loading}
dataSource={tableData}
columns={columns}
rowKey={'id'}
pagination={{
total: total,
onChange: onPageChange,
}}
/>

再次刷新页面,一切正常,分页功能完美实现。

禁用sizeChanger

如果你不希望用户改变每页显示的条数,可以禁用sizeChanger功能,只需要在pagination属性中添加showSizeChanger: false即可。

1
2
3
4
5
6
7
8
9
<Table
loading={loading}
dataSource={tableData}
columns={columns}
rowKey={'id'}
pagination={{
showSizeChanger: false, // 禁用每页条数选择器
}}
/>

禁用分页

如果你十分确定,你的数据一页就能展示完,比如10条以内的数据,那么你可以禁用分页功能。只需要在Table组件中添加pagination={false}属性即可。

1
2
3
4
5
6
7
<Table
loading={loading}
dataSource={tableData}
columns={columns}
rowKey={'id'}
pagination={false} // 禁用分页
/>

今天就到这里了,祝大家编程愉快,我们明天见!觉得有用,就点个关注吧!