项目需求:
在使用ant design form动态增减表单项Form.List时,Form.List中有多组表单项,一组中的最后一个表单项的校验规则是动态的,该组为最后一组时,最后一个表单项是非必填项,其他时候为必填项。假设动态增加了两组表单项,均为填写内容,在必填项校验被触发后,删除了第二组表单项,此时仅剩一组表单项,想要最后一个表单项的校验状态不再显示必填项提示。如下图所示:

想要的效果,最后一个表单项不显示必填项提示: 
解决思路:
使用动态校验规则,获取到最后一组的索引,使用form.validateFields重新触发校验规则。
代码如下:
- import React, { useState } from 'react';
- import { Form } from 'antd';
-
- const App = () => {
-
- const [lastIndex, setLastIndex] = useState(false); // form表单最后一组数据的索引
-
- const [form] = Form.useForm();
-
- useEffect(() => {
- // 减少表单项时,重新触发表单验证,使form最后一组中最后一个表单项的验证状态不再显示必填项提示
- form.validateFields([['configs', lastIndex, 'lastFormOption']]);
- }, [lastIndex, form]);
-
- return (
- <Form form={form} initialValues={{ configs: [{}] }} >
- ……
- <Form.List name="configs">
- {(fields, { add, remove }) => (
- <>
- {fields.map(({ key, name, ...restField }, index) => {
- // 这里获取最后一组表单项索引
- setLastIndex(fields.length - 1);
- return (
- <Row
- key={key}
- >
- ……
- <Col span={5}>
- <Form.Item
- {...restField}
- name={[name, 'lastFormOption']}
- rules={[
- {
- required: (fields.length - 1) == index ? false : true,
- message: '请选择……',
- },
- ]}
- >
- <Select
- options={options}
- disabled={(fields.length - 1) == index}
- placeholder="最后一条自定义条件为非必填项"
- />
- Form.Item>
- Col>
- <Col span={2}>
- <MinusCircleOutlined onClick={() => remove(name)} />
- Col>
- Row>
- )
- })}
- <Form.Item >
- <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
- 新增
- Button>
- Form.Item>
- >
- )}
- Form.List>
- Form>
- );
- };
- export default App;
上述解决方式中,如果App作为一个子组件用到了ForwardRef,会出现下面的告警:
Warning: Cannot update a component (`ForwardRef(AddRemoveFormItems)`) while rendering a different component (`Field`). To locate the bad setState() call inside `Field`, follow the stack trace as described……
解决方案:去掉setLastIndex(fields.length - 1);等相关代码,将规则校验放在删除表单组的操作中。代码如下:
- <MinusCircleOutlined style={{ fontSize: 24 }} onClick={() => {
- remove(name);
- form.validateFields();
- }} />