Recently I wrote a little thing that mimics my original project written in Vue and changes it to react grammar. I wrote an editable form, stumbled along the way, and wanted to record the bugs. First the renderings and code paste up, the main use is react+ ANTd

Click “Edit” to open the popover window. In the popover window, TAB switches to display different forms, form + editable table. The operation bar “+” in the table adds a row of editable data in the table

Table/index.js

import React, { useState }from 'react'
import { Row,Col,Card, Table, Tag, Divider, Modal, Button } from 'antd';
import ModalData from './model'


const App = (props) = > {
  console.log(props,The '-')
  const [isModalVisible, setIsModalVisible] = useState(false);
  const columns = [
    {
      title: 'Name'.dataIndex: 'name'.key: 'name'.render: text= > <a>{text}</a>}, {title: 'Age'.dataIndex: 'age'.key: 'age'}, {title: 'Address'.dataIndex: 'address'.key: 'address'}, {title: 'Tags'.key: 'tags'.dataIndex: 'tags'.render: tags= > (
        <label>
          {tags.map(tag => {
            let color = tag.length > 5 ? 'geekblue' : 'green';
            if (tag === 'loser') {
              color = 'volcano';
            }
            return (
              <Tag color={color} key={tag}>
                {tag.toUpperCase()}
              </Tag>
            );
          })}
        </label>),}, {title: 'Action'.key: 'action'.align:'center'.render: (record) = > (
        <label>
          <a onClick={()= >ShowModal (record)} > edit</a>
          <Divider type="vertical" />{/ *<Button onClick={()= >ShowModal (record)} > delete</Button>* /}<a onClick={()= >ShowModal (record)} > delete</a>
        </label>),},];const data = [
    {
      key: '1'.name: 'John Brown'.age: 32.address: 'New York No. 1 Lake Park'.tags: ['nice'.'developer'],}, {key: '2'.name: 'Jim Green'.age: 42.address: 'London No. 1 Lake Park'.tags: ['loser'],}, {key: '3'.name: 'Joe Black'.age: 32.address: 'Sidney No. 1 Lake Park'.tags: ['cool'.'teacher'],}];const showModal = (row) = > {
    setIsModalVisible(true);
  };
  const handleCancel = () = > {
    setIsModalVisible(false);
  }
  const handleOk = (form={},data) = > {
    setIsModalVisible(false);
    console.log(form,data,'pp---')}return (
    <label>
      <Row gutter={16} className="gutter-row">
        <Col md={24}>
          <Card title="Basic Table + Simple popup" bordered={false}>
            <Table columns={columns} dataSource={data} />
          </Card>
        </Col>
      </Row>
      {isModalVisible && <ModalData close={()= >{
        handleCancel()
      }} saveOk={(form,data)=>{ handleOk(form,data) }}/>}
      {/* {isModalVisible && <ModalData  />* /}}</label>
  );
};
const la = '111'
export default() = > (<App/>
)
Copy the code

Table/model/index.js

import React from 'react'
import Basic from './modules/base'
import EditTableData from './modules/editTableData'
import { Modal, Tabs, Spin } from "antd";

export default class ModalData extends React.Component{
  constructor(){
    super(a)this.state = {
      isModalVisible:true,
      currentTab:'basicColumns',
      tableData:[]
    }
  }
  componentWillMount(){
    this.setState({
      isModalVisible:this.props.isModalVisible
    })
    this.basicColumns = [
      {title:'Operation type',editable:true,dataIndex:'name'},
      {title:'name',editable:true,dataIndex:'age'},
      {title:'description',editable:true,dataIndex:'address'}]this.associationColumns = [
      {title:'Front operation',editable:true,dataIndex:'name'},
      {title:'Associated permissions',editable:true,dataIndex:'age'},
      {title:'Associated operations',editable:true,dataIndex:'address'}]this.dataViewColumns = [
      {title:'fields',editable:true,dataIndex:'name'},
      {title:'description',editable:true,dataIndex:'address'}
    ]
  }
  componentWillUpdate(){
    console.log(22)
  }
  componentDidMount(){
    console.log(11)
  }
  handleOk = () => {
    // console.log(this.tabData,'this.formRefThree.props')
    const form = this.formRef.props.form;
    form.validateFields((err, fieldsValue) => {
      if(! err) { console.log(this.tabData,'pp---00---');
        this.props.saveOk(fieldsValue,this.tabData)
      }
    });
  }
  saveTable(data){
    console.log(data,this.state.currentTab,'data---')
    this.tabData = {
      [this.state.currentTab]:data
    }

  }
  changeTab(key){
    console.log(key,'key---')
    this.setState({
      currentTab:key
    })
  }
  render(){
    
    return (
      <Modal
        title="Edit" 
        width={650}
        destroyOnClose
        visible
        onOk={ () => this.handleOk() } 
        onCancel={ () => this.props.close()}
      >
        <Tabs onChange={(key)=>this.changeTab(key)} >
          <Tabs.TabPane tab="Basic Information" key="basicColumns">
            <span>
              <Basic wrappedComponentRef={(form) => this.formRef = form}/>
              <EditTableData basicColumns={this.basicColumns} saveTable={(data)=>this.saveTable(data)}/>
            </span>
          </Tabs.TabPane>
  
          <Tabs.TabPane tab="Associated permissions" key="associationColumns">
            <EditTableData associationColumns={this.associationColumns} saveTable={(data)=>this.saveTable(data)}/>
          </Tabs.TabPane>
          <Tabs.TabPane tab="Data View" key="dataViewColumns">
            <EditTableData dataViewColumns={this.dataViewColumns} saveTable={(data)=>this.saveTable(data)}/>
          </Tabs.TabPane>
        </Tabs>
      </Modal>
    )
  }
}
Copy the code

Table/model/modules/base.js

import React from 'react'
import { Form, Input, Select, Radio } from 'antd';
const { Option } = Select;

// const Basic = (props) => {
class Basic extends React.Component{
  formRef = React.createRef();
  // const [form] = Form.useForm();
  onGenderChange(value){
    switch (value) {
      case 'male':
        this.props.form.setFieldsValue({
          note: 'Hi, man! '});return;

      case 'female':
        this.props.form.setFieldsValue({
          note: 'Hi, lady! '});return;

      case 'other':
        this.props.form.setFieldsValue({
          note: 'Hi there! '});return;
    }
  }
  onFinish(values){
    console.log(values);
    console.log(this.props.form.getFieldsValue,'09900--')
  }
  
  render(){
    console.log(this.props.form.getFieldValue('gender'),'990 -')
    const { form } = this.props;
    const { getFieldDecorator, getFieldValue} = form; 
    return (
      <div>
        <Form ref={this.formRef} layout="inline" name="control-hooks" onFinish={this.onFinish.bind(this)}>
          <Form.Item label="Permission identification" required>
            {getFieldDecorator("note")(<Input placeholder="Please enter"/>)}
          </Form.Item>
          <Form.Item label="Permission Name" required>
          {getFieldDecorator("name")(<Input placeholder="Please enter"/>)}
          </Form.Item>
          <Form.Item label="requiredMark" name="State" required>
            {getFieldDecorator("requiredMark")(
              <Radio.Group>
                <Radio.Button value="optional"> Enable </ radio.button > < radio.button value="disabled"> Disable </ radio.button > </ radio.group >)} </ form.item > < form.item name="gender" label="Classification" required>
            {getFieldDecorator("gender")(
              <Select style={{width: '250px'}} placeholder="Please select" onChange={this.onGenderChange.bind(this)} allowClear >
                <Option value="male"</Option> <Option value="female"> Tenant </Option> <Option value="other"} </Form.Item> {getFieldValue();'gender') = ='other' && <Form.Item name="customizeGender" label="Note">
            {getFieldDecorator("customizeGender")(<Input />)}
          </Form.Item>} 
        </Form>
      </div>

    )
  }
}
export default Form.create()(Basic)
Copy the code

Table/model/modules/editTable.js

import React, { useState } from 'react';
import { Table, Input, InputNumber,Divider, Popconfirm, Form, Typography } from 'antd';
import {PlusSquareOutlined} from '@ant-design/icons';
const { Provider, Consumer } = React.createContext()// Pass values between components
const originData = [];

for (let i = 0; i < 5; i++) {
  originData.push({
    key: i.toString(),
    name: `Edrward ${i}`,
    age: 32,
    address: `London Park no. ${i}`,
  });
}
class EditableCell extends React.Component{
  renderCell = ({getFieldDecorator}) => {
    const{ editing, dataIndex, title, Inputs, record, index, children, ... restProps } =this.props
    return ( <td {... restProps}> {editing ? ( <Form.Item style={{ margin:0, }} >
           {getFieldDecorator(dataIndex,{
             rules: [{
              required: true,
              message: 'Please enter'
            }],
            initialValue: record[dataIndex] 
           })( 
        )}
          </Form.Item>
        ) : ( children )}
      </td>
    );
  }
  render(){
    return <Consumer>{this.renderCell}</Consumer>
  }
}

class EditTableData extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      data:originData,
      editingKey:' '}}// Determine whether editable
  isEditing = record => record.key == this.state.editingKey

  / / initialization
  init(){
    console.log(this.props,'pp--')
    const data = this.props.basicColumns || this.props.dataViewColumns || this.props.associationColumns || []
    this.columns = [
      ...data,
      {
        title: ()=>{
          return<span> Operation <Divider type="vertical" /><PlusSquareOutlined style={{color:"# 333"}} onClick={()=>this.addColumns()}/></span>
        },
        width:'20%',
        dataIndex: 'operation',
        render: (_, record) => {
          const { editingKey } = this.state
          const editable = this.isEditing(record);
          return editable ? (
            <span>
              <Consumer>
                {
                  form => (
                  <a onClick={() => thisDivider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider"vertical"  />
              <Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure to cancel?" onConfirm={this<span> <a disabled={editingKey! <span> <a disabled={editingKey! =' '} onClick={()=>thisDivider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider"vertical"  />
                <Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure to cancel?" onConfirm={()=>thisDelete (record. Key)} > < a > delete < / a > < / Popconfirm > < / span >). }},]; }/ / add
  addColumns = () => {
    const newData = [...this.state.data]
    newData.push({
      key: newData.length,
      name: ``,
      age: ' ',
      address: ``
    })
    this.setState({
      data:newData
    })
  }
  / / edit
  edit = (key) => {
    this.setState({
      editingKey:key
    })
  }
  / / delete
  delete = (key) => {
    const newData = [...this.state.data]
    const index = newData.findIndex(item=>item.key == key)
    newData.splice(index,1)
    this.setState({
      data:newData
    })
  }
  / / save
  save = (form,key) => {
    form.validateFields((error,row)=>{
      if(error){
        return
      }
      const newData = [...this.state.data]
      const index = newData.findIndex(item=>item.key == key)
      if(index > -1) {const item = newData[index]
        newData.splice(index,1, {... item,... row }) }this.setState({
        editingKey:' ',
        data:newData
      })
      this.props.saveTable(newData)
    })

  }

  / / cancel
  cancel = () => {
    this.setState({
      editingKey: ' '
    })
  }

  render(){
    this.init()
    console.log(this.columns,'columns')
    const columns = this.columns.map(col => {
      if(! col.editable){return col
      }
      return {
        ...col,
        onCell:record => ({
          record,
          Inputs:Input,
          dataIndex:col.dataIndex,
          title:col.title,
          editing:this.isEditing(record)
        })
      }
    })
    return (
      <Provider value={this.props.form}>
        <Table bordered style={{marginTop:'30px'}} components={{
          body:{
            cell:EditableCell
          }
        }} columns={columns} dataSource={this.state.data} pagination={false}/>
      </Provider>
    )
  }
}


export default Form.create()(EditTableData)
Copy the code