antd table合并行的columns配置动态修改列名导致的引用问题

需求背景

我需要实现一个如下的多个相邻行合并为一行的功能,之后又接到需求,要求当用户切换冗余场景时,替换Table中的某一列的名称,具体如下截图所示
在这里插入图片描述
在这里插入图片描述

踩坑

我想到的办法是,当切换冗余场景时,将Table的columns进行序列化替换文本,于是写了以下代码:

let cols = JSON.parse(JSON.stringify(columns).replace(/:"总存储量"/g, ':"存储量"'));
setColumns(cols)

接着,setColumns成功,组件重新渲染,发现合并行失效了,文本替换也没有实时更新,变成和我的判断逻辑(汇总统计=总存储量,其他统计子类=存储量)相反了。

分析,为什么会如此

分两个原因描述

1、合并行为什么失效了?

因为antd的Table组件的columns是在初始化配置的时候一次性绑定的一个引用配置,因此,后续必须使用同一个引用配置columns才能使合并行效果生效,而我使用了序列化字符串再转回js对象,这个过程产生了新的引用,导致合并行的一些效果对应不上原先的配置,因此合并行效果失效

2、文本替换为什么没有即时生效,而是走了相反的判断逻辑结果?

如果我们没有使用setState去更新columns配置,就会组件不重新render,导致UI不能及时获取到最新的值,因此会产生我们拿到的值是上一次的值的情况

正确的做法

使用splice对原引用配置columns进行替换:

useEffect(() => {
    if (isEqualRedd) {
      columns.splice(7, 1, {
        title: '总存储量',
        dataIndex: 'sumStorgCap',
        render: (text) => {
          return text + 'T';
        },
        onCell: (_, index) => {
          return {
            rowSpan: _[`${'id'}RowSpan`],
          };
        },
      });
      _setColumns(columns);
    } else {
      columns.splice(7, 1, {
        title: '存储量',
        dataIndex: 'storgCap',
        render: (text) => {
          return text + 'G';
        },
      });
      _setColumns(columns);
    }
  }, [navType, isEqualRedd]);

完整Table组件代码

import { Empty, Table } from 'antd';
import React, { useEffect, useState } from 'react';
import styles from './MergeCellTable.less';

const MergeCellTable = (props) => {
  const { navType, pagination, onPageChange, isEqualRedd } = props;
  const [data, setData] = useState([]);
  const [_columns, _setColumns] = useState([]);

  let columns = [
    {
      title: 'key',
      dataIndex: 'key',
      className: styles.notShowCol,
    },
    {
      title: '编号',
      dataIndex: 'id',
      onCell: (_, index) => {
        return {
          rowSpan: _[`${'id'}RowSpan`],
        };
      },
    },
    {
      title: '治理优先级',
      dataIndex: 'govPrior',
      onCell: (_, index) => {
        return {
          rowSpan: _[`${'id'}RowSpan`],
        };
      },
    },
    {
      title: '资产名',
      dataIndex: 'astNm',
    },
    {
      title: '所属中心',
      dataIndex: 'blngCtr',
    },
    {
      title: '责任人',
      dataIndex: 'princ',
    },
    {
      title: '冗余场景',
      dataIndex: 'redundSmlClass',
    },
    {
      title: '总存储量',
      dataIndex: 'sumStorgCap',
      render: (text) => {
        return text + 'T';
      },
      onCell: (_, index) => {
        return {
          rowSpan: _[`${'id'}RowSpan`],
        };
      },
    },
    {
      title: '冗余类型',
      dataIndex: 'redundType',
      onCell: (_, index) => {
        return {
          rowSpan: _[`${'id'}RowSpan`],
        };
      },
    },
  ];

  useEffect(() => {
    setData(props.dataSet);
  }, [props.dataSet]);

  useEffect(() => {
    if (navType === '其他') {
      columns.splice(4, 1, {
        title: '所属团队',
        dataIndex: 'blngCtr',
      });
    } else {
      columns.splice(4, 1, {
        title: '所属中心',
        dataIndex: 'blngCtr',
      });
    }
    _setColumns(columns);
  }, [navType, isEqualRedd]);

  useEffect(() => {
    if (isEqualRedd) {
      columns.splice(7, 1, {
        title: '总存储量',
        dataIndex: 'sumStorgCap',
        render: (text) => {
          return text + 'T';
        },
        onCell: (_, index) => {
          return {
            rowSpan: _[`${'id'}RowSpan`],
          };
        },
      });
      _setColumns(columns);
    } else {
      columns.splice(7, 1, {
        title: '存储量',
        dataIndex: 'storgCap',
        render: (text) => {
          return text + 'G';
        },
      });
      _setColumns(columns);
    }
  }, [navType, isEqualRedd]);

  const onChange = (page) => {
    onPageChange && onPageChange(page);
  };

  return (
    <Table
      columns={_columns}
      dataSource={data}
      bordered
      pagination={false}
      rowClassName={(record, index) => (index % 2 === 1 ? 'even' : 'odd')}
      onChange={onChange}
      locale={{
        emptyText: (
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据" />
        ),
      }}
    />
  );
};

export default MergeCellTable;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
antd table 合并可以通过设置表格的 column 属性中的 render 函数来实现。具体步骤如下: 1. 在 column 中设置需要合并的 dataIndex 和 render 函数。 2. 在 render 函数中,判断当前单元格是否需要合并,如果需要,则返回一个包含合并信息的对象,否则返回单元格的值。 3. 在表格的 rowSpan 和 colSpan 属性中设置需要合并数和数。 4. 如果需要在合并后的单元格中显示图片,可以在 render 函数中返回一个包含图片的 JSX 元素。 下面是一个示例代码,用于将表格中的第一和第二合并,并在合并后的单元格中显示图片: ``` import { Table } from 'antd'; const dataSource = [ { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park', image: 'https://example.com/image1.png', }, { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', image: 'https://example.com/image2.png', }, { key: '3', name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park', image: 'https://example.com/image3.png', }, ]; const columns = [ { title: 'Name', dataIndex: 'name', key: 'name', render: (text, record, index) => { const obj = { children: text, props: {}, }; if (index === 0) { obj.props.rowSpan = 2; } if (index === 1) { obj.props.rowSpan = 0; } return obj; }, }, { title: 'Age', dataIndex: 'age', key: 'age', render: (text, record, index) => { const obj = { children: text, props: {}, }; if (index === 0) { obj.props.rowSpan = 2; } if (index === 1) { obj.props.rowSpan = 0; } return obj; }, }, { title: 'Address', dataIndex: 'address', key: 'address', }, { title: 'Image', dataIndex: 'image', key: 'image', render: (text, record, index) => { if (index === 0) { return <img src={text} alt="image" />; } return null; }, }, ]; const DemoTable = () => { return <Table dataSource={dataSource} columns={columns} />;}; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值