react+antd单个Form.Item刷新其他Form.Item验证状态

项目场景: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>
    );
}
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!感谢您的提问。针对您的问题,我可以给出以下解决思路: 1. 在需要添加 Tooltip 复制功能的 Form.Item 的 label 属性上添加 Tooltip 组件,并设置其 title 属性为需要复制的内容; 2. 在需要添加复制功能的 input 输入框中添加 ref 属性,并在组件的 componentDidMount 生命周期中获取该 ref,并将其绑定到复制按钮的 onClick 事件中; 3. 在复制按钮的 onClick 事件中,通过获取 input 输入框的 value 值,并将其复制到剪贴板中实现复制功能。 下面是具体的代码实现,仅供参考: ``` import React, { Component } from 'react'; import { Form, Input, Tooltip, Button } from 'antd'; import { CopyOutlined } from '@ant-design/icons'; class Demo extends Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { this.copyBtn.addEventListener('click', this.handleCopy); } componentWillUnmount() { this.copyBtn.removeEventListener('click', this.handleCopy); } handleCopy = () => { const { value } = this.inputRef.current.input; const textarea = document.createElement('textarea'); textarea.innerText = value; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); } render() { return ( <Form> <Form.Item label={ <Tooltip title="复制内容" placement="topLeft"> 需要复制的内容: </Tooltip> } > <Input ref={this.inputRef} /> <Button ref={ref => (this.copyBtn = ref)} icon={<CopyOutlined />} /> </Form.Item> </Form> ); } } export default Demo; ``` 希望这可以帮助到您!如果您还有其他问题,可以继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值