嵌套动态表单 Antd

Nested Dynamic Forms Antd

所以我将这个动态表单放在一起(酒店房间),您还可以在其中创建动态表单(房间床)。它有效,我可以添加房间和床位,并且对象数组在 console.log (onSubmit) 中返回。

codesandbox: https://codesandbox.io/s/charming-hermann-nzpbu?file=/src/App.js

问题: 如果你添加 room1 和 room2 然后删除 room1,数组的长度保持为 2,现在它有“未定义的床”,并且当你向其他房间添加床时它会不断增长!帮我解决这个问题:

当您按下下一步(在控制台中)时返回对象。正如您所看到的,数组没有减去,但当我删除房间时它也没有定义床:

listingDescription: "ss"
listingName: "aa"
pricePerMonth: 1
rooms: Array(2)
0: {roomname: "room2", beds: Array(1)}
1: {beds: undefined}

主要形式:

import React from 'react';
import { useStateMachine } from 'little-state-machine';
import { useForm } from 'react-hook-form';
import { Row, Col, Input, InputNumber, Button, Form, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import FormControl from 'components/UI/FormControl/FormControl';
import AddListingAction from './AddListingAction';
import { FormHeader, Title, FormContent, FormAction } from './AddListing.style';
import BedForm from "./BedForm";

const BasicInformation = ({ setStep }) => {
  const { action, state } = useStateMachine(AddListingAction);
  const { control, register, errors, setValue, handleSubmit } = useForm();


  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <Form onFinish={(e) => onSubmit(e)}>
      <FormContent>
        <FormHeader>
          <Title>Step 1: Start with the basics</Title>
        </FormHeader>
        <Row gutter={30}>
          <Col sm={12}>
            <FormControl
              label='Listing Name'
              htmlFor='listingName'
              error={errors.listingName && <span>This field is required!</span>}
            >
              <Form.Item
                id='listingName'
                name='listingName'
                defaultValue={state.data.listingName}
                control={control}
                placeholder='Write a name for your listing here'
                rules={[
                  {
                    required: true,
                  },
                ]}
              >
                <Input />
              </Form.Item>
            </FormControl>
          </Col>
          <Col sm={12}>
            <FormControl
              label='Price Per Night (USD)'
              htmlFor='pricePerMonth'
            >
              <Form.Item
                name='pricePerMonth'
                id='pricePerMonth'
                defaultValue={state.data.pricePerMonth}
                control={control}
                placeholder='00.00'
                rules={[
                  {
                    required: true,
                    pattern: /^[0-9]*$/,
                  },
                ]}
              >
                <InputNumber min={0} />
              </Form.Item>
            </FormControl>
          </Col>
        </Row>
        <FormControl
          label='Listing Description'
          htmlFor='listingDescription'
          error={
            errors.listingDescription && <span>This field is required!</span>
          }
        >
          <Form.Item
            id='listingDescription'
            name='listingDescription'
            defaultValue={state.data.listingDescription}
            control={control}
            placeholder='Tell people about your listing, rooms, location & amenities'
            rules={[
              {
                required: true,
              },
            ]}
          >
            <Input.TextArea rows={5} />
          </Form.Item>
        </FormControl>
        <FormControl
          label='How many rooms does your listing have?'
          error={errors.guest && <span>This field is required!</span>}
        >
          {/* This is the Dynamic room Adder */}
          <Form.List name='rooms'>
            {(fields, { add, remove }) => {
              return (
                <div>
                  {fields.map((field) => (
                    <Space
                      key={field.key}
                      style={{ display: 'flex', marginBottom: 8 }}
                      align='start'
                    >
                      <Form.Item
                        {...field}
                        name={[field.name, 'roomname']}
                        fieldKey={[field.fieldKey, 'roomname']}
                        rules={[
                          { required: true, message: 'Missing room name' },
                        ]}
                      >
                        <Input placeholder='Room Name' />
                      </Form.Item>

                      {/* This is the Dynamic bed Adder */}

                      <Form.Item>
                      <BedForm fieldKey={field.key} />
                      </Form.Item>

                      <MinusCircleOutlined
                        onClick={() => {
                          remove(field.name);
                          console.log(field)
                        }}
                      />
                    </Space>
                  ))}

                  <Button
                    type='dashed'
                    onClick={() => {
                      add();
                    }}
                    block
                  >
                    <PlusOutlined /> Add room
                  </Button>
                </div>
              );
            }}
          </Form.List>
        </FormControl>
      </FormContent>

      <FormAction>
        <div className='inner-wrapper'>
          <Button type='primary' htmlType='submit'>
            Next
          </Button>
        </div>
      </FormAction>
    </Form>
  );
};

export default BasicInformation;

儿童形态 (BedForm)

import React from 'react';

import { Form, Input, Button, Space, Select } from 'antd';
import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
const { Option } = Select;

//@ATT:this was created to make nested dynamic elements! This is hard!
const BedForm = (props) => {
  return (
    <>
      <Form.List name={[props.fieldKey, 'beds']}>
        {(beds, { add, remove }) => {
          return (
            <div>
              {beds.map((bed, index2) => (
                <Space
                  key={bed.key}
                  style={{ display: 'flex', marginBottom: 8 }}
                  align='start'
                >
                  <Form.Item
                    // name={"aar"}
                    {...bed}
                    name={[bed.name, 'bed']}
                    fieldKey={[bed.fieldKey, 'bed']}
                    key={index2}
                    // noStyle
                    rules={[
                        {
                          required: true, message: 'Beds Missing'
                        },
                      ]}
                  >
                    <Select  placeholder="Please select a Bed Type">
                      <Option value='double'>Double(2 person)</Option>
                      <Option value='single'>Single (1 person)</Option>
                      <Option value='king'>King Size (2 person)</Option>
                      <Option value='queen'>Queen Size (2 person)</Option>
                      <Option value='Bunk'>Bunk Bed (1 person)</Option>
                      <Option value='sofa'>Sofa Bed (1 person)</Option>
                    </Select>
                  </Form.Item>
                  {/* <MinusCircleOutlined
                    onClick={() => {
                      remove(bed.name);
                    }}
                  /> */}
                </Space>
              ))}
              <Form.Item>
                <Button
                  type='dashed'
                  onClick={() => {
                    add();
                  }}
                >
                  <PlusOutlined /> Add Bed
                </Button>
              </Form.Item>
            </div>
          );
        }}
      </Form.List>
    </>
  );
};

export default BedForm;

传递 field.name 而不是 field.key 或 App.js

上的 fieldKey

https://codesandbox.io/s/trusting-wind-elsdz?file=/src/App.js