ant design form动态增减表单项Form.List如何进行动态校验规则

项目需求:

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

想要的效果,最后一个表单项不显示必填项提示:

解决思路:

使用动态校验规则,获取到最后一组的索引,使用form.validateFields重新触发校验规则。

代码如下:

javascript 复制代码
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);等相关代码,将规则校验放在删除表单组的操作中。代码如下:

javascript 复制代码
<MinusCircleOutlined style={{ fontSize: 24 }} onClick={() => {
  remove(name);
  form.validateFields();
}} />
相关推荐
khalil102012 小时前
代码随想录算法训练营Day-41动态规划08 | 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III
数据结构·c++·算法·leetcode·动态规划
无限进步_13 小时前
【C++】AVL树完全解析:从平衡因子到四种旋转
c语言·开发语言·数据结构·c++·后端·算法·github
浅念-13 小时前
LeetCode最短路必看:BFS算法原理+经典题解
数据结构·c++·算法·leetcode·职场和发展·bfs·宽度优先
流年如夢14 小时前
顺序表的应用 --> 简单通讯录的实现
c语言·数据结构
如君愿14 小时前
考研复习 Day 31 | 习题--计算机网络 第五章(运输层 中)、数据结构 图 (中)
数据结构·计算机网络·课后习题
代码地平线14 小时前
【数据结构】二叉树详解:全代码逐行解析+6道LeetCode高频OJ题图解
数据结构·算法·leetcode
流年如夢14 小时前
顺序表(LeetCode)
c语言·数据结构·leetcode·职场和发展
say_fall15 小时前
校招必看:八大排序算法原理、复杂度与高频面试题
数据结构·c++·算法·排序算法
浅念-1 天前
刷穿LeetCode:BFS 解决 Flood Fill 算法
数据结构·c++·算法·leetcode·职场和发展·bfs·宽度优先
im_AMBER1 天前
手撕hot100之矩阵!看完这篇就AC~
javascript·数据结构·线性代数·算法·leetcode·矩阵