前言
大家在用antd做后台管理系统,尤其是table和form的组合时是不是会有这么个苦恼,既想要拥抱function component,又看着这么多的useState头疼。如果用了mobx或者别的状态管理工具还好说,没用的话可能就是一大长串的useState了。
这时,ahooks就出来了(虽然文档写的不是特别全,但是看代码提交记录和issues还是很及时的,而且解决这类问题也挺好用
useRequest
useAntdTable和useRequest的api都一样,所以这里简单介绍一下useRequest
const {
data,
error,
loading,
run,
params,
cancel,
refresh,
mutate,
fetches,
} = useRequest(service, {
manual,
initialData,
refreshDeps,
onSuccess,
onError,
formatResult,
cacheKey,
loadingDelay,
defaultParams,
pollingInterval,
pollingWhenHidden,
fetchKey,
refreshOnWindowFocus,
focusTimespan,
debounceInterval,
throttleInterval,
ready,
throwOnError,
});
其实就是帮我们做了一次接口的处理,包括:自动请求或者手动请求、轮询、防抖、分页。。。只要有关接口的都帮我们处理了,可以参考文档查看具体每个字段的含义。useRequest-ahooks
useAntdTable
我们先简单的写一个使用useAntdTable的form和table联动页面
import { Button, Card, Form, Input, Table, Space, Popconfirm } from "antd";
import React, { useState } from "react";
import { useRequest, useAntdTable, useDebounceFn } from "ahooks";
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
id: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
});
}
const Home = () => {
const [form] = Form.useForm();
// 模拟请求接口
const getTableData = ({ current, pageSize }, formData) => {
// 如果是真实get请求,要加上这些
// let query = `page=${current}&size=${pageSize}`;
// Object.entries(formData).forEach(([key, value]) => {
// if (value) {
// query += `&${key}=${value}`;
// }
// });
return new Promise((resolve, reject) => {
let result = data;
// 模拟form的过滤操作
if (formData.name) {
result = data.filter((item) => item.name.includes(formData.name));
}
resolve(result);
}).then((res) => ({
// 注意:这里的格式必须是list,否则可以通过formatResult转化
list: res,
total: res.length,
}));
};
const deleteItemByIds = (id) => {
console.log(id);
};
const { tableProps, search } = useAntdTable(getTableData, {
defaultPageSize: 5,
form,
});
const { run: autoSearch } = useDebounceFn(search.submit, { wait: 500 });
const { run: deleteItem } = useRequest((id) => deleteItemByIds(id), {
manual: true,
});
const columns = [
{
title: "姓名",
dataIndex: "name",
key: "name",
},
{
title: "年龄",
dataIndex: "age",
key: "age",
},
{
title: "住址",
dataIndex: "address",
key: "address",
},
{
title: "操作",
key: "action",
render: (text, record) => (
<Space size="middle">
<a>编辑</a>
<Popconfirm
title="确认删除吗"
onConfirm={async () => {
await deleteItem(record.id);
search.submit();
}}
okText="确认"
cancelText="取消"
>
<a href="#">删除</a>
</Popconfirm>
</Space>
),
},
];
return (
<Card style={{ margin: 24 }}>
<Form form={form} onValuesChange={autoSearch}>
<Form.Item label="名字" name="name">
<Input />
</Form.Item>
<Form.Item label="年龄" name="age">
<Input />
</Form.Item>
<Form.Item label="住址" name="address">
<Input />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
style={{ marginRight: 20 }}
onClick={search.submit}
>
查询
</Button>
<Button onClick={search.reset}>重置</Button>
</Form.Item>
</Form>
<Table rowKey="id" columns={columns} {...tableProps} />
</Card>
);
};
export default Home;
从上面我们可以看出来使用还是非常方便的,基本所有的操作都是一句代码,简单分析一下:
const { tableProps, search } = useAntdTable(getTableData, {
defaultPageSize: 5,
form,
});
这里因为没有设置manual: true,所以会直接发起getTableData这个请求,我们打印一下tableProps对象
useAntdTable在发起请求后,会将数据以及table的设置存到tableProps里
再打印一下search对象
在接收到form实例后,会返回search对象,而search对象又包含了触发form的各种操作 看到这,只能说妙~啊
而接来下触发form的方式,就简单的调用一下search对象的方法就ok了🤓,比起再通过设置各种state是不是方便多了
const { run: deleteItem } = useRequest((id) => deleteItemByIds(id), {
manual: true,
});
这句代码run会向外面暴露出一个手动调用该request的方法,即deleteItem,再通过deleteItem触发(id) => deleteItemByIds(id),针不戳
基本的用法大概如此,欢迎各位小伙伴一起入坑👏