When using a Form component in ANTD, if you use a custom component, you do not get the value of the custom component when saving.

Here’s the solution from ANTD:

Form.Item wrapped with the name property. The Form control automatically adds value (or other property specified by valuePropName) onChange (or other property specified by trigger)

We can do data collection synchronization through the onChage automatically added to the form control.

The parent component:

import React, { Fragment, useState, useEffect, forwardRef, useRef } from 'react';
import HeaderTable from './headerTable';

const BasicForm = forwardRef((props, ref) = > {
  const { record } = props;
  const [ form ] = Form.useForm();

    <Form
          name="taskForm"
          ref={ref}
          form={form}
        >
        <Row gutter={20}>
            <Col span={24}>
              <Form.Item  name="headers" label={'Header'} >
                <HeaderTable ref={headerTableRef} record={record} />
              </Form.Item>
            </Col>
          </Row>
    </Form>
export default BasicForm;
Copy the code

Child components:

import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef} from 'react';
import { Transfer, Divider, Table, Button, Input, message, Select } from 'antd';
import AddRowTable from '@components/AddRowTable';/ / Table component

const { Option } = Select;

const DATATYPE = [
	{
		id: 1.name: 'int'
	}, {
		id: 2.name: 'varchar'}]const HeaderTable = ( props, ref ) = > {
	const { record, isLook, onChange } = props;
	const addRowTable = useRef();
	const [ sourceData, setSourceData ] = useState([]);
	const [ columns, setColumns ] = useState([]);
	const [ targetKeys, setTargetKeys ] = useState([]);
	const [ headerList, setHeaderList ] = useState([]);

	useEffect(() = > {
		if (record && record.id) {// Assign values to incoming data when editing
			setHeaderList(record.sourceInfoMap.headers)
		}
	}, [record])
        
        // Set the columns header
        useEffect(() = > {
        const columns = [
	{
            title: 'Parameter Name'.dataIndex: 'name'.render: (text, record) = > {
		return (
			<Input value={text} onChange={tableItemChange.bind(this, record, 'name')} / >); }}, {title: 'operation'.dataIndex: 'operation'.align: 'center'.render: (text, record, index) = > {
		return (
                    <a onClick={delHandle.bind(this, record.index)} >'Delete'</a>
                        );
		}
	}];
        
        setColumns(columns);
        
        },[])

	// Add a line
	const handleAddTableRow = () = > {
		setHeaderList(headerList= > [...headerList, {}]);
		onChange(headerList= > [...headerList, {}])
	};


	// Delete a line
	const delHandle = (record, index) = > {
		setHeaderList(headerList= > {
			headerList.splice(index, 1);
			onChange(headerList)
			return [...headerList];
		});
	};

	// Table data changed
	const tableItemChange = (data, keyField, evt) = > {
		const value = evt.target ? evt.target.value : evt;
		data[keyField] = value;
		onChange(headerList)
	};

	return <div>
		<AddRowTable
			ref={addRowTable}
			dataSource={headerList}
			columns={columns}
			isCanAdd={isLook}
      disabled={isLook}
			addItem={handleAddTableRow.bind(this)}
		/>
	</div>
}

export default HeaderTable;
Copy the code

This allows you to use custom components in your form and get values uniformly. It’s not just the input field that you can do this with, all of the components, once you get the value, you give it to the onChange method, you can get the value uniformly.