4.7 KiB
4.7 KiB
| name | description |
|---|---|
| search-state-persistence | Search state persistence via tools.router.query. Invoke when implementing search/table pages with SearchForm + Table + pagination that need to preserve query params across refreshes. |
搜索状态持久化
通过 tools.router.query 实现搜索条件持久化,刷新页面后搜索条件和分页状态保留在 URL 查询参数中。
核心 API
import { tools } from "@cqsjjb/jjb-common-lib";
const { router } = tools;
router.query 是一个响应式对象,对其赋值会同步更新 URL 查询参数。
完整模式
import React, { useState, useEffect } from "react";
import { Button, Form, Select, Space, Table, Tag } from "antd";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import SearchForm from "~/components/SearchForm";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { tools } from "@cqsjjb/jjb-common-lib";
const { router } = tools;
const MyPage = (props) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
/** 搜索/刷新数据 */
const handleSearch = () => {
setLoading(true);
// 实际请求...
setTimeout(() => setLoading(false), 500);
};
/** 重置搜索 */
const handleReset = (values) => {
router.query = {
...router.query,
...values,
current: 1,
size: 10,
};
handleSearch();
};
/** 初始化:将 URL 中的查询条件回填到表单 */
useEffect(() => {
form.setFieldsValue(router.query);
}, []);
const columns = [
// ...列定义
];
return (
<PageLayout title="页面标题">
<SearchForm
style={{ marginBottom: 24 }}
form={form}
loading={loading}
formLine={[
<Form.Item key="fieldName" name="fieldName">
<ControlWrapper.Input label="字段名" placeholder="请输入" allowClear />
</Form.Item>,
]}
onReset={handleReset}
onFinish={(values) => {
router.query = {
...router.query,
...values,
current: 1,
size: 10,
};
handleSearch();
}}
/>
<Table
rowKey="id"
columns={columns}
dataSource={data}
scroll={{ y: props.scrollY }}
loading={loading}
pagination={{
total: total,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `共 ${total} 条`,
current: router.query.current,
pageSize: router.query.size,
onChange: (page, pageSize) => {
router.query = {
...router.query,
current: page,
size: pageSize,
};
handleSearch();
},
}}
/>
</PageLayout>
);
};
export default AntdTableFuncControl(MyPage);
关键规则
1. 初始化回填
在 useEffect 中将 router.query 的值回填到表单,确保刷新后表单显示与 URL 一致:
useEffect(() => {
form.setFieldsValue(router.query);
}, []);
注意:router.query 中所有值均为字符串,而 DatePicker / RangePicker 需要 dayjs 对象。当表单包含日期字段时,必须手动转换:
useEffect(() => {
searchForm.setFieldsValue({
...router.query,
dateRange:
router.query.startTime && router.query.endTime
? [dayjs(router.query.startTime), dayjs(router.query.endTime)]
: undefined,
});
}, []);
2. 搜索/重置写入
搜索提交(onFinish) 和重置(onReset) 时,将表单值与默认分页合并写入 router.query:
router.query = {
...router.query,
...values, // 表单值
current: 1, // 重置到第一页
pageSize: 10, // 默认页大小
};
3. 翻页写入
分页变化时,仅更新 current 和 pageSize,保留已有搜索条件:
onChange: (page, pageSize) => {
router.query = {
...router.query, // 保留已有搜索条件
current: page,
pageSize,
};
handleSearch();
};
4. 组件装饰器
页面组件必须用 AntdTableFuncControl 包裹以支持表格功能:
export default AntdTableFuncControl(MyPage);
注意事项
router.query是响应式的:赋值会触发 URL 更新,且刷新后值仍然保留router.query中所有值均为字符串类型(URL query 的特性),使用current和pageSize时注意隐式类型转换- 默认值
current: 1, pageSize: 10是约定,可根据实际需求修改 onReset回调的values参数是重置后的表单值(所有字段清空/恢复默认后的值)