andt Table的扩展嵌套表单异步请求数据使用

 问题:

依赖expandedRowRender渲染嵌套表单,有多条数据可能会请求n次嵌套表单的数据,点击操作,若是页面更新,又会再次请求n次,并且页面会有卡顿闪烁问题。

问题产生的原因

个人感觉:expandedRowRender被触发的原因可能就是动态数据渲染的更新产生。

解决思路

不要依赖expandedRowRender做异步请求,而是只是做页面展示。

主要涉及的属性

  • expandedRowKeys(展开的行,控制属性【格外用法:可以用在刷新展示,自动扩展更新异步嵌套表单数据】),
  • onExpand(点击展开图标时触发【用于异步请求】),
  • onExpandedRowsChange(展开的行变化时触发【对expandedRowKeys数据实时更新】)
  •  dataSource(展示表单数据)

思路:点击有加号的图表,请求异步嵌套表单数据,把数据存储为该条数据的mychildren字段上,更新表格dataSource的数据,其实就会触发expandedRowRender更新渲染。【注释:字段设置不要为children,ProTable会出问题】

实现

1. 所需设置的数据

    //当前所有点击扩展的数据的key集合(一般是id)。
    const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]); 
    // 表格总数据
    const [tableData, setTableData] = useState<API.ProjectListItem[]>([]);

2. 把异步数据存在父节点数据中,一般有多层,就写了一个方法

  const addChildrenToTreeNode = (tree: API.ProjectListItem[], targetId: string, childrenData: API.ProjectListItem[] | null) => {
        function traverseAndModify(node: API.ProjectListItem) {
            if (node.id === targetId) {
                node.mychildren = childrenData;
                return true;
            }
            // 如果节点有子节点,递归搜索每一个子节点
            if (node.mychildren) {
                for (let child of node.mychildren) {
                    if (traverseAndModify(child)) {
                        return true;
                    }
                }
            }

            return false;
        }
        const newThree = JSON.parse(JSON.stringify(tree));
        // 开始递归遍历树
        newThree.forEach(traverseAndModify);
        // 返回修改后的树
        return newThree;
    }

3. 点击展开按钮时,去请求异步数据,并保存在总数据中

 const onExpand = async (expanded: boolean, record: any) => {
        // record.hasChild 这个是判断他是否有子集的。
        if (expanded && record.hasChild) {
            const { data } = await listProject({ id: record.id })
            const tree = addChildrenToTreeNode(tableData, record.id, data);
            setTableData(tree)
        } else {
            const tree = addChildrenToTreeNode(tableData, record.id, null);
            setTableData(tree)
        }
    }

4. 渲染嵌套表格

 const ExpandedRowRender: React.FC<{ value: any, expanded?: boolean; }> = ({ value, expanded }) => {
        if (expanded && value?.mychildren?.length > 0 && value.hasChild) {
            return (
                <ProTable
                    rowKey="id"
                    columns={columns}
                    headerTitle={false}
                    search={false}
                    expandable={{
                        expandedRowKeys: expandedRowKeys,
                        onExpand: (expanded, record) => { onExpand(expanded, record) },
                        onExpandedRowsChange: (expandedRows) => {
                            setExpandedRowKeys(expandedRows as string[]);
                        },
                        expandedRowRender: (record, _, __, expanded) => <ExpandedRowRender value={record} expanded={expanded} />,
                        rowExpandable: (record) => record?.hasChild || false,
                    }}
                    options={false}
                    dataSource={value?.mychildren}
                    pagination={false}
                />
            )
        } else {
            return null;
        }
    };

5. 最后一步展示

 <ProTable<API.ProjectListItem, API.ProjectListParams>
                headerTitle={'项目列表'}
                actionRef={actionRef}
                rowKey="id"
                search={{ labelWidth: 120 }}
                pagination={{
                    pageSize: 10,
                }}
                dataSource={tableData}
                expandable={{
                    expandedRowKeys: expandedRowKeys,
                    onExpand: (expanded, record) => { onExpand(expanded, record) },
                    onExpandedRowsChange: (expandedRows) => {
                        setExpandedRowKeys(expandedRows as string[]);
                    },
                    expandedRowRender: (record, _, __, expanded) => <ExpandedRowRender value={record} expanded={expanded} />,
                    rowExpandable: (record) => record?.hasChild || false,
                }}
                toolBarRender={() => [
                    <Button><PlusOutlined /> 新建</Button>
                ]}
                request={async (params) => {
                    const data = await pageProject(params);
                    setTableData(data.data);
                    setExpandedRowKeys([]); // 这一步很关键,记得清空
                    return data;
                }}
                columns={columns}
            />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值