在开发管理系统时,表格是非常常见的 UI 组件,通常需要支持分页、筛选等功能。然而,用户在操作表格时,如新增、修改导致切换页面,返回表格页面时,如何保留之前的筛选条件和分页信息呢?本篇文章将通过一个简单的示例,教你如何使用 useTableState
自定义 Hook 来解决这一问题。
实现思路
我们需要自定义一个 hooks
: useTableState
来实现操作表格与持久化参数的联系。useTableState
中通过 sessionStorage
来持久化表格的分页状态和筛选条件。
sessionStorage
是一种简单的浏览器存储方式,在页面会话期间有效,可以在页面刷新或者切换时保持数据状态,但关闭浏览器后数据会丢失。通过这个方法,我们能够让用户返回表格时,自动恢复之前的分页和筛选状态。
当然如果你觉得,希望让用户下次打开网页时,参数也能被记住,那也可以考虑用 localstorage
替换掉 sessionStorage
useTableState
代码及解析
首先,我们看一下 useTableState
自定义 Hook 的实现:
typescript
import { useState } from "react";
interface TableState {
pagination: {
pageSize: number;
current: number;
total?: number;
};
searchParams: any;
}
const useTableState = (tableName: string) => {
const storedPagination = sessionStorage.getItem(`${tableName}_pagination`);
const storedSearchParams = sessionStorage.getItem(`${tableName}_searchParams`);
const [pagination, setPagination] = useState<TableState["pagination"]>(
!!storedPagination
? JSON.parse(storedPagination)
: {
pageSize: 10,
current: 1,
}
);
const [searchParams, setSearchParams] = useState(!!storedSearchParams ? JSON.parse(storedSearchParams) : {});
const handleTableChange = (pagination: any, filters: any) => {
// 存储筛选项和页码到 sessionStorage
sessionStorage.setItem(`${tableName}_pagination`, JSON.stringify(pagination));
sessionStorage.setItem(`${tableName}_searchParams`, JSON.stringify(filters));
setPagination(pagination);
setSearchParams(filters);
};
return {
pagination,
searchParams,
handleTableChange,
};
};
export default useTableState;
在这段代码中,useTableState
Hook 做了以下几件事:
- 读取存储数据 :从
sessionStorage
中获取之前保存的分页和筛选条件,如果存在则使用这些值,若没有则使用默认值。 - 状态管理 :使用
useState
保存分页和筛选条件的状态。 - 更新状态 :通过
handleTableChange
函数更新分页和筛选条件,同时将新状态保存到sessionStorage
中,确保用户返回时能够恢复之前的操作。
如何在表格页面使用这个 Hook
接下来,我们在表格页面中如何使用这个 useTableState
来实现状态持久化。以下是一个基于 Ant Design Pro 的表格页面示例:
typescript
const columns: ProColumns<TExamPart>[] = [
{
title: "姓名",
dataIndex: "name",
},
{
title: "年龄",
dataIndex: "age",
}
];
const UserManagement = () => {
const ref = useRef<ActionType>();
/************ 关键代码开始 ************/
const formRef = useRef<ProFormInstance>();
/************ 关键代码结束 ************/
const [showModifyModal, setModifyModal] = useState<boolean | string>(false);
const [showDeleteModal, setShowDeleteModal] = useState<false | string>(false);
/************ 关键代码开始 ************/
const { pagination, searchParams, handleTableChange } = useTableState("guideManager");
useEffect(() => {
formRef.current?.setFieldsValue({
...searchParams,
});
}, []);
/************ 关键代码结束 ************/
return (
<PageContainer breadcrumb={undefined}>
<ProTable
actionRef={ref}
/************ 关键代码开始 ************/
formRef={formRef}
/************ 关键代码结束 ************/
toolBarRender={() => [
<Button key="add-btn" type="primary" onClick={() => setModifyModal(true)}>
新增
</Button>,
]}
rowKey="id"
columns={[
...columns,
{
title: "操作",
search: false,
render: (_index, { id }) => {
return (
<Space>
<a
onClick={() => {
setModifyModal(id);
}}
>
修改用户
</a>
<a
onClick={() => {
setShowDeleteModal(id);
}}
>
删除
</a>
</Space>
);
},
},
]}
/************ 关键代码开始 ************/
request={(values) => {
return request<{
data: TUser[];
}>("/api/xxx/list", {
method: "GET",
params: {
...values,
},
}).then((res) => {
const { current, pageSize, ...rest } = values;
handleTableChange(
{
current,
pageSize,
total: res.data.length,
},
{
...searchParams,
...rest,
}
);
return {
data: res.data,
success: true,
};
});
}}
onChange={(pagination, filters) => {
handleTableChange(pagination, { ...searchParams, ...filters });
}}
pagination={{
...pagination,
}}
/************ 关键代码结束 ************/
/>
<ModifyModal
showModal={showModifyModal}
handleCancel={() => setModifyModal(false)}
handleOk={() => {
ref.current?.reload();
setModifyModal(false);
}}
/>
<DeleteModal
title="删除用户"
content="确定要删除该用户吗?"
showModal={!!showDeleteModal}
handleCancel={() => setShowDeleteModal(false)}
handleOk={() => {
if (showDeleteModal) {
request<{ data: boolean }>("/api/xxx/delete", {
method: "DELETE",
data: {
id: showDeleteModal,
},
}).then(({ data }) => {
if (data) {
message.success("删除成功!");
ref.current?.reload();
setShowDeleteModal(false);
}
});
}
}}
/>
</PageContainer>
);
};
export default UserManagement;
formRef
用于绑定表单,以便在加载时能够填充表单字段useTableState
用于管理分页和筛选条件,它会通过sessionStorage
持久化表格的状态。useEffect
空依赖用于在组件加载时,设置表单的默认值(即筛选条件)。`request
方法会根据分页和筛选条件从后端获取用户数据,并在数据返回后,更新表格的分页和筛选条件。onChange
方法更新页码参数(因为后端没有做分页)- 将
pagination
属性改为受控的
总结
通过以上操作,就可以轻松实现了表格分页和筛选状态的持久化,使得用户在返回表格时能够自动恢复之前的操作状态,希望可以对阅读文章的你有帮助!