ant design v4可编辑表格class版

直接上index.tsx可以根据官网修改的可以直接运行

import {Form, Input, InputNumber, Popconfirm, Select, Table} from 'antd';
import React from "react";

const {Option} = Select;

const layout = {
  labelCol: {span: 8},
  wrapperCol: {span: 16},
};

const originData: any = [];

for (let i = 0; i < 100; i++) {
  originData.push({
    key: i.toString(),
    name: `Edrward ${i}`,
    age: 32,
    address: `London Park no. ${i}`,
  });
}

class EditableCell extends React.Component<any, any> {
  constructor(props) {
    super(props);
  }

  getInput = () => {
    if (this.props.inputType === 'number') {
      return <InputNumber/>;
    }
    return <Input/>;
  };

  render() {
    const {
      editing,
      dataIndex,
      title,
      inputType,
      record,
      index,
      children,
      ...restProps
    } = this.props
    return (
      <td {...restProps}>
        {editing ? (
          <Form.Item name={dataIndex} label={dataIndex} style={{margin: 0}} rules={[{
            required: true,
            message: `Please Input ${title}!`,
          }]}>
            {this.getInput()}
          </Form.Item>
        ) : (
          children
        )}
      </td>
    );

  }


}

class EditableTable extends React.Component<any, any> {
  formRef = React.createRef();

  constructor(props) {
    super(props);
    this.columns = [
      {
        title: 'name',
        dataIndex: 'name',
         '25%',
        editable: true,
      },
      {
        title: 'age',
        dataIndex: 'age',
         '15%',
        editable: true,
      },
      {
        title: 'address',
        dataIndex: 'address',
         '40%',
        editable: true,
      },
      {
        title: 'operation',
        dataIndex: 'operation',
        render: (text, record) => {
          const {editingKey} = this.props.state;
          const editable = this.isEditing(record);
          return editable ? (
            <span>
            <a
              onClick={() => this.save(record.key)}
              style={{
                marginRight: 8,
              }}
            >
              Save
            </a>
              <Popconfirm title="Sure to cancel?" onConfirm={() => this.cancel(record.key)}>
                <a>Cancel</a>
              </Popconfirm>
          </span>
          ) : (
            <a disabled={editingKey !== ''} onClick={() => this.edit(record)}>
              Edit
            </a>
          );
        },
      },
    ];

  }

  isEditing = record => record.key === this.props.state.editingKey;

  edit(record: any) {
    this.formRef.current.setFieldsValue({
      name: '',
      age: '',
      address: '',
      ...record,
    });
    this.props.handleEdit(record)
  };

  cancel = () => {
    this.props.handleCancel()
  };

  save(key: any) {
    const row = this.formRef.current.getFieldsValue();
    const newData = [...this.props.state.data];
    const index = newData.findIndex((item) => key === item.key);
    if (index > -1) {
      const item = newData[index];
      newData.splice(index, 1, {...item, ...row});
    } else {
      newData.push(row);
    }
    this.props.handleSave(newData)
  };


  render() {
    const components = {
      body: {
        cell: EditableCell,
      },
    };

    const mergedColumns = this.columns.map(col => {
      if (!col.editable) {
        return col;
      }

      return {
        ...col,
        onCell: record => ({
          record,
          inputType: col.dataIndex === 'age' ? 'number' : 'text',
          dataIndex: col.dataIndex,
          title: col.title,
          editing: this.isEditing(record),
        }),
      };
    });
    return (
      <Form ref={this.formRef} component={false}>
        <Table
          components={components}
          bordered
          dataSource={this.props.state.data}
          columns={mergedColumns}
          rowClassName="editable-row"
          pagination={{
            onChange: this.cancel,
          }}
        ></Table>
      </Form>

    );

  }
}

export default class Demo extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      data: originData,
      editingKey: '',
    }
  }

  handleEdit = (record: any) => {
    this.setState({editingKey: record.key});
  }

  handleCancel = () => {
    this.setState({editingKey: ''});
  }

  handleSave = (newData) => {
    this.setState({
      data: newData,
      editingKey: ''
    })
  }


  render() {
    const parentMethods = {
      handleEdit: this.handleEdit,
      handleCancel: this.handleCancel,
      handleSave: this.handleSave,
      state: this.state
    };
    return (
      <EditableTable {...parentMethods}/>
      // <MyForm/>
    )
  }
}

注意点1:
传值问题:
子组件修改父组件的state必须 在父组件中定义,然后在子组件使用this.props进行调用父组件的方法,这个方法最后i修改state。

注意点2:
form的使用
v4的class版使用form那是真坑啊,耗费我好几天时间,记录下。

v4中使用form传递的时候
使用下面代替useForm()

formRef = React.createRef();

v4中Form.Item不支持设置默认值,但是这里的场景是需要单独设置的,所以使用

    this.formRef.current.setFieldsValue({
      name: '',
      age: '',
      address: '',
      ...record,
    });

设置当前单元格的值
获取当前单元格的值用

    const row = this.formRef.current.getFieldsValue();

具体看上面的代码

原文地址:https://www.cnblogs.com/c-x-a/p/14082254.html