项目场景:antd 的Form内的Form.List 内Form.Item 单个表单修改刷新其他表单的校验结果
项目所用技术:react+antd+Form
Form组件内使用Form.List组件内来写一个数组对象形式的Form.Item并从上到下校验下面的数值不能小于上面的数值
可能比较绕,建议重复阅读
功能点:
Form,Form.List,Form.Item;组件
Form.useForm的validateFields()主动触发校验
Form.List的新增与删除
Form.Item的单个校验触发多个校验
功能代码
提示:剔除了多余代码,直接搬运可能会有问题:
如有更优解欢迎各位大佬分享方案
import React, { useState, useEffect, useRef, useCallback } from "react";
import { Form, Input, Button, Radio, InputNumber, Switch, Row, Col } from "antd";
const FormItem = Form.Item;
export default function StepOne(props) {
// 声明form数据
const [formRef] = Form.useForm();
// 用来判断是否有未通过校验的记录避免无限调用
const ifcall = useRef(false);
//自定义校验方法
const validateReceiveCondition = (rule, value, callback) => {
//获取formRef内的activityPrizeList数组数据
let newList = [...formRef.getFieldsValue().activityPrizeList];
// 记录需要更新的字段
let newVaild=[];
const bols=newList.every((item,index,row)=>{ //item:循环对象,index:下标,row:循环主体数组
//添加需要更新的字段到数组内
newVaild.push(['activityPrizeList',index,'receiveCondition'])
if(row.length==index+1) return true
return item.receiveCondition<=row[index+1].receiveCondition
})
//发现违规数据
if (!bols) {
//抛出错误信息
callback('奖品天数条件必须从上往下,递增设置');
//标记有违规数据
ifcall.current=true;
} else {
//callback方法不管是否需要抛出异常都需要调用一次
callback();
//判断是否有违规值
if(ifcall.current){
//如果没有违规值则重新触发一次Form的校验刷新校验状态
//规定触发校验的Form.Item
formRef.validateFields(newVaild)
//无违规值标记为false避免无限调用formRef.validateFields()导致页面卡死
ifcall.current=false;
}
}
};
return (
<Form
form={formRef}
name="control-ref"
labelCol={{span: 5,}}
wrapperCol={{span:19,}}
>
//这个form.Item可以省略不加,这里是为了使用Form.Item的label
<FormItem name="activityPrizeList" label="添加阶梯奖励">
//注意:Form.List没有label属性但是需要加name
<Form.List name="activityPrizeList" >
//固定参数fields数组add添加数组remove删除数组
{(fields, { add, remove }, { errors }) => (
<>
<Button
type="primary"
disabled={status!=3 ?false:true}
//增加一条数据
onClick={() => fields.length < 10 && add({
receiveCondition: 1,
}))}
>
添加数据({fields.length}/10)
</Button>
{
fields.length > 0 && <ul className="mt18">
//循环渲染
{fields.map((field, index) => (
<li className="mt18" key={index}>
<div className="fl fcC frSb">
<div className="fg1 mr26">
<FormItem
className="ml10"
style={{ marginRight: "150px" }}
name={[field.name, 'receiveCondition']}
rules={
[
{
//自定义校验方法
validator: validateReceiveCondition,
},
]
}
//默认值
initialValue={1}
>
<InputNumber
disabled={status!=3 ?false:true}
style={{ width: '240px' }}
addonBefore="大于等于"
addonAfter="天可领取"
min={1}
precision={0}
placeholder="请填写天数"
/>
</FormItem>
</div>
//删除当前数据
<div type="dashed" onClick={() => remove(field.name)}>
删除
</div>
</div>
</li>
))}
</ul>
}
//配合Form.List使用
<Form.ErrorList errors={errors} />
</>
)}
</Form.List>
</FormItem>
</Form>
);
}