ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.3k stars 1.36k forks source link

🐛[BUG] EditableProTable onChange is triggered with old data after onSave #8610

Open erdemkeren opened 3 months ago

erdemkeren commented 3 months ago

🐛 Bug description

I need to update the table datasource after I get the response from onSave method.

However, after I call my setDataSource function (also provided to EditableProTable with onChange={setDataSource}, the component calls the same setDataSource method with existing information and overwrites my chanes.

📷 Reproduction steps

🏞 Expected results

Data source is updated with the data from backend and it is not overwritten by the table component.

💻 Reproduction code

Uuid is empty on init. onSave adds it (please leave it blank for the purpose of reproduction.

Note: My case is different and uuid is just some test name.

https://codesandbox.io/p/sandbox/wizardly-currying-t7qcgk

import "./styles.css";
import React, { useState } from "react";
import { Button } from "antd";
import { EditableProTable } from "@ant-design/pro-components";

export default function App() {
  const [dataSource, _setDataSource] = useState([
    {
      id: 1,
      uuid: null,
    },
  ]);

  const setDataSource = (data) => {
    console.log("setDataSource was called with", data);

    _setDataSource(data);
  };

  const columns = [
    {
      title: "id",
      dataIndex: "id",
      fieldProps: {
        disabled: true,
      },
    },
    {
      title: "uuid",
      dataIndex: "uuid",
    },
    {
      title: "Actions",
      align: "center",
      valueType: "option",
      render: (_text, record, _number, action) => (
        <>
          <Button
            type="link"
            key="edit"
            onClick={() => action?.startEditable?.(record.id)}
          >
            Edit
          </Button>
        </>
      ),
    },
  ];

  const onSave = (_rowKey, data, _row) => {
    return new Promise((res, rej) => {
      res([
        {
          id: 1,
          uuid: "test",
        },
      ]);
    }).then((data) => {
      setDataSource(data);

      return data;
    });
  };

  return (
    <div className="App">
      <h1>Hello Bug</h1>
      <EditableProTable
        rowKey="id"
        value={dataSource}
        onChange={setDataSource}
        columns={columns}
        editable={{
          type: "single",
          onSave,
          saveText: "Save",
          actionRender: (_row, _config, dom) => [dom.save],
        }}
      />
    </div>
  );
}

© Version information

🚑 Other information

I am open to built in callback function to update the data on save like promise.resolve.