优雅的使用antd的form和table–初探ahooks

时间:2021-1-8 作者:admin

前言

大家在用antd做后台管理系统,尤其是table和form的组合时是不是会有这么个苦恼,既想要拥抱function component,又看着这么多的useState头疼。如果用了mobx或者别的状态管理工具还好说,没用的话可能就是一大长串的useState了。

这时,ahooks就出来了(虽然文档写的不是特别全,但是看代码提交记录和issues还是很及时的,而且解决这类问题也挺好用

useRequest

useAntdTableuseRequest的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

我们先简单的写一个使用useAntdTableformtable联动页面

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),针不戳

基本的用法大概如此,欢迎各位小伙伴一起入坑👏

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。