首页 > 解决方案 > 当antd表中的列值发生变化时,如何立即更新汇总值?

问题描述

我想显示一个“简单”表,其中行是动态添加的。记录有一个属性harnamount。两者都用于使用公式显示总金额harn * amount / 100

这是我的列定义:

const columns = [
  {
    //omitted;
  },
  {
    title: "Amount",
    dataIndex: "amount",
    render: (text, record, index) => {
        return (
            <InputNumber
                defaultValue={record.amount}
                min={0}
                formatter={value => `${value}g`}
                parser={value => value?.replace('g', '') || 0}
                onChange={e => {
                   record.amount = e
                }}
            />
        )
    }
  }

使用摘要定义:

const summary = (data: readonly TableFoodType[]) => {
    let totalHarn: number = 0
    data.forEach(({ harn, amount }) => {
        totalHarn += harn * (amount / 100)
    })
    return (
        <Table.Summary.Row>
            <Table.Summary.Cell index={0}><span>Total: </span></Table.Summary.Cell>
            <Table.Summary.Cell index={1}>
                {totalHarn}
            </Table.Summary.Cell>
        </Table.Summary.Row>
    )
}

我的目标是在用户更新单元格中输入的金额时更新摘要,而无需明确保存,但我不知道如何将更改后的值从InputNumber直接写回记录中。就目前而言,摘要没有更新。

对于这样一个看似简单的任务,可编辑单元格(https://ant.design/components/table/#components-table-demo-edit-cell)的文档看起来非常复杂,所以我想知道,如果有简单的方法,我现在没有看到。

整个组件并不是为持久化数据而设计的,所以我现在要做的就是立即更改和显示它。

标签: reactjstypescriptantd

解决方案


这似乎过于复杂。您的组件可以存储data状态并setDataonChange.InputNumber

Ant Design 演示代码Form在输入周围使用了一些组件来进行验证。它们还具有附加状态,以控制当前正在编辑哪个组件。在这个简单的版本中,整个“金额”列呈现为可编辑输入,并且更改立即发布到组件状态。

最烦人的部分是onChange函数接收到的值可能是numberstringnull。我将字符串转换为数字并忽略空值。

const [data, setData] = useState(initialData);
const columns = [
...
    title: "Amount",
    dataIndex: "amount",
    render: (text, record, index) => {
        return (
            <InputNumber
                defaultValue={record.amount}
                min={0}
                formatter={value => `${value}g`}
                parser={value => value?.replace('g', '') || 0}
                onChange={(newValue) => {
                  if (newValue) {
                    const number =
                      typeof newValue === "string"
                        ? parseFloat(newValue)
                        : newValue;
                    setData(
                      data.map((row, i) =>
                        i === index ? { ...record, amount: number } : row
                      )
                    );
                  }
            />
        )
    }
]

由于这些更改会立即反映在 中data,因此您不必更改摘要中的任何内容。


推荐阅读