Ant Design 动态循环form表单验证的问题

THIS
  • 716

场景:
我需要动态的在页面中 添加相同的的表单 进行验证,使用的场景如下:

image.png

代码如下:

// 渲染通栏运营位置配置
const RenderBannerConfig = forwardRef((_, ref) => {

  // 维护form数据列表
  const fromList = [
    {
      FormInfo:{
        labelCol: { span: 4 },
        wrapperCol: { span: 20 },
      },
      ItemInfo:[
        {
          name:"bannerConfigImg",
          label:"上传图片:",
          Child: () => {
            return (
              <PicListUploader
                placeholder="请上传图片"
                width={1080}
                minHeight={1080}
                maxHeight={5760}
              />
            )
          }
        },
        {
          name:"bannerConfigLink",
          label:"配置链接:",
          rules:[
            {
              required: true,
              whitespace:true,
              message: '配置链接接为必填项'
            }
          ],
          Child: () => {
            return (
              <Input placeholder="请输入配置链接" maxLength="50" style={{ width: "480px" }} />
            )
          }
        },
        {
          name:"bannerConfigUser",
          label:"展示用户:",
          rules:[
            {
              required: true,
              message: '展示用户信息为必填项'
            }
          ],
          Child:() => {
            return (
              <Select mode="tags"  placeholder="请输入人群包ID" style={{ width: '480px' }} />
            )
          }
        },
        {
          name:"bannerConfigInvalidTime",
          label:"时间:",
          rules:[
            {
              required: true,
              message: '时间信息为必填项'
            }
          ],
          Child:() => {
            return (
              <RangePicker
                showTime={{ format: 'HH:mm' }}
                format="YYYY-MM-DD HH:mm"
              />
            )
          }
        }
      ]
    }
  ]

  const [form] = Form.useForm();
  const [formList, setformList] = useState(fromList) 

  return (
    <>
      <div style={{ margin: '20px 0' }}><strong>通栏运营位配置:</strong></div>
      {
        formList.map((item, index) => {
          return (
            <Form 
            form={form}
            key={index}
            name={`bannerInfoForm${index}`}
            {...item.FormInfo}
            > 
            {item.ItemInfo.map((card, _index)=> {
              const { Child }  = card
              return (
                <Form.Item
                  key={_index}
                  name={card.name}
                  label={card.label}
                  rules={card.rules}
                >
                  <Child />
                </Form.Item>
              )
            })}
            </Form>
          )
        })
      }
      <Button onclick={() => form.validateFields()}></Button>
    </>
  )
})

问题:我循环了整个fromList数据、但是验证的时候获取不到values的值;浏览器打印结果如下:

image.png

请问一下是什么原因

回复
阅读 1.4k
2 个回答
✓ 已被采纳

查阅了资料发现 其实antd 不支持上图的写法。
可以参考:动态表单
以下是具体代码:

// 渲染通栏运营位置配置
const RenderBannerConfig = forwardRef((_, ref) => {
  const [form] = Form.useForm();

  // 初始默认数据
  const initialValues = {
      bannerInfoFormItem:[
      {
        key: 0,
        name: 0,
        fieldKey: 0,
        isListField: true,
        bannerConfigImg:'',
        bannerConfigLink:'',
        bannerConfigUser:[],
        bannerConfigInvalidTime:'',
     }
    ]
  }
  // 添加
  const addItem = async (callback) => {
    try{
      const result = await form.validateFields()
      result &&  callback()
      console.log(result)
      
    }catch(error){
      console.log(error)    
    }
    
    console.log('添加')
  }

  // 区域提交
  const submit = () => {
    console.log('submit')
  }

  return (
    <>
      <div style={{ margin: '20px 0' }}><strong>通栏运营位配置:</strong></div>
      <Form 
        {...formLayout}
        form={form}
        name="bannerInfoForm"
        initialValues={initialValues}
        ref={ref}
      >
      <Form.List name="bannerInfoFormItem">
        { (fields, {add, remove }) => (
          <>
            { fields.map(( item, index) => (
              <div key={item.key} style={ { paddingBottom:'20px'}}>
                <Form.Item  
                  name={[item.name, 'bannerConfigImg']}
                  fieldKey={[item.fieldKey, 'bannerConfigImg']}  
                  label="上传图片"
                >
                  <PicListUploader
                    placeholder="请上传图片"
                    width={1080}
                    minHeight={1080}
                    maxHeight={5760}
                  />
                </Form.Item>
                <Form.Item
                  name={[item.name, 'bannerConfigLink']}  
                  fieldKey={[item.fieldKey, 'bannerConfigLink']} 
                  label="配置链接:"
                  rules={[
                    {
                      required: true,
                      whitespace:true,
                      message: '配置链接接为必填项'
                    }
                  ]}
                >
                <Input placeholder="请输入配置链接" maxLength="50" style={{ width: "480px" }} />
              </Form.Item>
              <Form.Item
                name={[item.name, 'bannerConfigUser']} 
                fieldKey={[item.fieldKey, 'bannerConfigUser']}  
                label="展示用户:"
                rules={[
                  {
                    required: true,
                    message: '展示用户信息为必填项'
                  }
                ]}
              >
                <Select mode="tags" getPopupContainer={triggerNode => triggerNode.parentNode} placeholder="请输入人群包ID" style={{ width: '480px' }} />
              </Form.Item>
              <Form.Item
                  name={[item.name, 'bannerConfigInvalidTime']} 
                  fieldKey={[item.fieldKey, 'bannerConfigInvalidTime']}   
                  label="时间:"
                  rules={[
                    {
                      required: true,
                      message: '时间信息为必填项'
                    }
                  ]}
                >
                <RangePicker
                  showTime={{ format: 'HH:mm' }}
                  format="YYYY-MM-DD HH:mm"
                />
              </Form.Item>
              </div>
            ))}

            <Form.Item {...formItem}>
              <div style={ { width:"180px", display:"flex", justifyContent:"space-between"}}>
                <Button onClick={() => addItem(add)}>添加</Button>
                <Button onClick={ submit} type={'primary'} >保存</Button>
              </div>
            </Form.Item>
          </>
        )}
      </Form.List>
      </Form>
    </>
  )
})

参考资料:

表单嵌套自定义组件,手动传递props
Child: (props) => {

        return (
          <Input {...props} placeholder="请输入配置链接" maxLength="50" style={{ width: "480px" }} />
        )
      }
宣传栏