美文网首页
[Hook]useTable

[Hook]useTable

作者: 小丸子啦啦啦呀 | 来源:发表于2022-10-30 17:05 被阅读0次

后台管理系统中必定会出现的组件就是表格页面,并且一个系统中往往有多个表格页面。
表格页面的业务逻辑,有许多相似之处,包括:

  1. 获取数据源
  2. 刷新数据源
  3. 分页
  4. 查询
  5. loading

因此,我发现在重构之前,每一个表格页面,都有一套几乎一模一样的逻辑:

import { Table } from "antd";
import { mock, Random } from "mockjs";
import React, { useEffect, useState } from "react";

const fetchUsers = (pageIndex, pageSize) => {
  return Promise.resolve(
    mock({
      "total|10-100": pageSize * 5.5,
      "list|10": [
        {
          "name|1": [
            Random.name(),
            Random.name(),
            Random.name(),
            Random.name(),
          ],
          "gender|1": ["male", "female"],
        },
      ],
    })
  );
};

const UserList = () => {
  const [isLoading, setIsLoading] = useState(false);
  const [dataSource, setDataSource] = useState([]);
  const [pageIndex, setPageIndex] = useState(10);
  const [pageSize, setPageSize] = useState(10);
  const [total, setTotal] = useState(0);

  useEffect(() => {
    fechDataSource();
  }, []);

  useEffect(() => {
    fechDataSource();
  }, [pageSize, pageIndex]);

  const fechDataSource = () => {
    setIsLoading(true);
    fetchUsers(pageIndex, pageSize)
      .then((res) => {
        setDataSource(res.list);
        setTotal(res.total);
      })
      .catch((error) => {
        console.error(error);
      })
      .finally(() => {
        setIsLoading(false);
      });
  };

  const pagination = {
    showSizeChanger: true,
    showTotal: () => `total: ${total}`,
    total,
    current: pageIndex,
    pageSize,
    onChange: (pageIndex, pageSize) => {
      setPageIndex(pageIndex);
      setPageSize(pageSize);
    },
  };

  const tableProps = {
    loading: isLoading,
    dataSource,
    columns: [
      {
        title: "Name",
        dataIndex: "name",
        key: "name",
      },
      {
        title: "Gender",
        dataIndex: "gender",
        key: "gender",
      },
    ],
    pagination,
  };

  return <Table {...tableProps} />;
};

export default UserList;

针对这个问题,我自定义了一个hook,将公共逻辑抽出来:

import { Table, Button } from "antd";
import { mock, Random } from "mockjs";
import React from "react";
import useTable from "../hooks/useTable";

const fetchUsers = (pageIndex, pageSize) => {
  return Promise.resolve(
    mock({
      "total|10-100": pageSize * 5.5,
      "list|10": [
        {
          "name|1": [
            Random.name(),
            Random.name(),
            Random.name(),
            Random.name(),
          ],
          "gender|1": ["male", "female"],
        },
      ],
    })
  );
};

const columns = [
  {
    title: "Name",
    dataIndex: "name",
    key: "name",
  },
  {
    title: "Gender",
    dataIndex: "gender",
    key: "gender",
  },
];

const UserListWithHook = () => {
  const { tableProps, query } = useTable(fetchUsers);

  const handleRefresh = () => {
    query();
  };

  return (
    <div>
      <Button onClick={handleRefresh}>Refresh</Button>
      <Table columns={columns} {...tableProps} />
    </div>
  );
};

export default UserListWithHook;
import { useEffect, useState } from "react";
import useAsync from "./useAsync";

const useTable = (fetchDataSource = () => Promise.resolve([])) => {
  const [params, setParams] = useState({
    pageSize: 10,
    pageIndex: 1,
  });

  const {
    res = {},
    isLoading,
    query,
  } = useAsync((originParams = {}) =>
    fetchDataSource({ ...params, ...originParams })
  );

  useEffect(() => {
    query(params);
  }, [params]);

  const pagination = {
    current: params.pageIndex,
    pageSize: params.pageSize,
    onChange: (index, pageSize) => {
      setParams({
        ...params,
        pageIndex: index,
        pageSize: pageSize || params.pageSize,
      });
    },
  };

  const tableProps = {
    dataSource: res.list,
    pagination,
    loading: isLoading,
  };

  return {
    tableProps,
    query,
    params,
  };
};

export default useTable;

用上自定义Hook useTable之后,UserList组件就清爽多了。
在usetTable中,还嵌套使用了另一个自定义hook,也就是useAsync,关于这个自定义组件的详细内容见https://www.jianshu.com/p/7b6f3aaa1a27?v=1667120684038

相关文章

  • [Hook]useTable

    后台管理系统中必定会出现的组件就是表格页面,并且一个系统中往往有多个表格页面。表格页面的业务逻辑,有许多相似之处,...

  • 堆利用的手法:

    malloc_hook realloc_hook+free_hook free_hook unsorted_bin...

  • hook原理小结

    常用的hook方式主要有导入表hook、导出表hook和inline hook三种。 一,导入表hook 首先需要...

  • 常用油猴Hook插件

    hook cookie hook 过debugger

  • react hook 状态与操作封装

    统一hook 数组hook

  • 遍历hook Dex中的类

    创建DexFile 遍历拿出所有类名 找到类对象,进行hook hook构造函数 hook方法 打印hook方法中的日志

  • frida native hook

    本篇介绍 frida 也支持hook native,本篇看下如何hook native hook native函数...

  • HOOK

    HOOK 一、HOOK概述 HOOK(钩子) 其实就是改变程序执行流程的一种技术的统称! 二、iOS中HOOK技术...

  • Windows Hook

    Hook 关于Hook 1.1什么是Hook 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可...

  • Android 进阶解密阅读笔记17

    Hook 技术 先来说我看完这章节对 Hook 的理解。Hook 关键在于找到合适的 Hook 点(也就是需要代理...

网友评论

      本文标题:[Hook]useTable

      本文链接:https://www.haomeiwen.com/subject/guxhtdtx.html