使用Ant Design时,多个子组件多个form表单的单独子组件的validateFields验证问题

Ant Design

Ant Design是一个内容丰富的组件库,在项目结构越来越复杂时,一个组件会用到多个子组件,多个子组件可能都会用到Ant Design的Form表单组件。

getFieldDecorator

在Form表单中,有一个可以对输入框进行限制的Api为getFieldDecorator,,主要作用是用于和表单进行双向绑定,在经过getFieldDecorator包装后,会自动添加value和onChange属性,数据同步将被Form接管。如此,会形成以下规则:
1、不需要用 onChange 来做同步,但还可以继续监听 onChange 等事件;
2、不能用控件的 value defaultValue 等属性来设置表单域的值,默认值可以用 getFieldDecorator 里的 initialValue;
3、不能用 setState,可以使用 this.props.form.setFieldsValue 来动态改变表单值。

import React, { Component } from 'react';
import {
  Form,
  Input,
  Select,
} from 'antd';
const { Option } = Select;
class AddOrUpdate extends Component {
  constructor(props) {
    super(props);
    this.state = { 
      currentData:''
    }
  }
  // 点击提交
  handleSubmit = e => {
    e.preventDefault();
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);
      }
    });
  };
  // 点击改变下拉框
  handleChange=(value)=>{
    console.log(`selected ${value}`);
  }
  UNSAFE_componentWillMount() {
    // 把form对象传递给父组件
    this.props.setForm(this.props.form);
  }
  render() {
    const { getFieldDecorator } = this.props.form;
    const { currentData,allClass,allSex } = this.props;
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
    };
    return ( 
      <>
        <Form {...formItemLayout} onSubmit={this.handleSubmit}>
          <Form.Item label="姓名">
            {getFieldDecorator('name', {
              // 校验规则
              rules: [
                {
                  required: true,
                  message: '不能为空',
                },
              ],
              // 文本框默认值
              initialValue:currentData?currentData.name:''
            })(<Input />)}
          </Form.Item>
          <Form.Item label="性别">
            {getFieldDecorator('sex', {
              rules: [
                {
                  required: true,
                  message: '不能为空',
                },
              ],
              initialValue:allSex?allSex[0]:''
            })(
              <Select style={{ width: 120 }} onChange={this.handleChange} >
                {
                  allSex.map(item=>{
                    return <Option value={item} key={item}>{item}</Option>
                  })
                }
              </Select>
            )}
          </Form.Item>
          <Form.Item label="班级">
            {getFieldDecorator('classGrade', {
              rules: [
                {
                  required: true,
                  message: '不能为空',
                },
              ],
              initialValue:allClass?allClass[0]:''
            })(
              <Select style={{ width: 120 }} onChange={this.handleChange} >
                {
                  allClass.map(item=>{
                    return <Option value={item} key={item}>{item}</Option>
                  })
                }
              </Select>
            )}
          </Form.Item>
        </Form>
      </>
     );
  }
}
// 经 Form.create() 包装过的组件会自带 this.props.form 属性,具有自动收集数据并校验的功能
export default Form.create()(AddOrUpdate);

在getFieldDecorator中有多种功能的Api,大家可自行查看官方文档:(https://3x.ant.design/components/form-cn/#components-form-demo-validate-other)。
下面着重说一下存在多个子组件使用Form表单的情况,如下所示:

多个子组件

return (
	{/* 子组件1-基础信息 */}
	<BaseInfo {...this.props} data={baseData}/>
	{/* 子组件2-产品信息 */}
	<ProductList {...this.props} data={productData} />
	{/* 子组件3-弹窗 触发条件为子组件2中的方法 */}
	<Modal
		title="审核"
		visible={visible}
		onCancel={()=>{
			this.setState({visible:false})
		}}
		onOk={this.onOk}
	>
		<CheckModal />
	<Modal/>
)

假设,在子组件1-BaseInfo、子组件2-ProductList、子组件3-CheckModal中均使用了Form表单,且都进行了rules必填验证,如何实现在弹窗出现时时,只对子组件3-CheckModal进行表单必填验证?

<Form.Item
	label="xxx"
	{getFieldDecorator('x',{
		{/* 必填项 */}
		rules:[{required:true, message:'xxx必填'}]
	})(
		<Input />
	)}
>
<Form.Item/>

使用ref获取子组件

在这里可以使用React的ref属性,ref可以挂载到组件上或DOM元素上,挂载在DOM元素上时,返回的是具体的DOM节点;挂载在组件上时,返回的是组件实例。

var Parent = React.createClass({
  render: function(){
    return (
      <div className = 'parent'>
        <Child ref = 'child'/>
      </div>
    )
  },
  componentDidMount(){
    console.log(this.refs.child); // 访问挂载在组件上ref
    console.log(this.refs.child.refs.update); // 访问挂载在dom元素上的ref
  }
})
var Child = React.createClass({
  render: function() {
    return (
        <div ref="test">
          <a ref="update">更新</a>
        </div>
    );
  }
});
ReactDOM.render(
  <Parent/>,
  document.getElementById('example')
);

打印结果
新版本的React已经不推荐我们使用ref string(ref=’ '),而是使用ref callBack(ref=>this.modalRef = ref)。
最终结果如下:

单独验证子组件

onOk=()=>{
	// 只对当前组件是否必填进行校验
	this.checkModal.validateFields((err,value)=>{
		if(err) {return}
	})
}
return (
	{/* 子组件1-基础信息 */}
	<BaseInfo {...this.props} data={baseData}/>
	{/* 子组件2-产品信息 */}
	<ProductList {...this.props} data={productData} />
	{/* 子组件3-弹窗 触发条件为子组件2中的方法 */}
	<Modal
		title="审核"
		visible={visible}
		onCancel={()=>{
			this.setState({visible:false})
		}}
		onOk={this.onOk}
	>
		{/* 使用ref callBack获取组件 */}
		<CheckModal ref={ref => this.checkModal = ref}/>
	<Modal/>
)
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ant-design 是一个流行的React UI组件库,提供了丰富的组件来帮助开发者快速构建用户界面。在ant-design中,表单验证是一个重要的功能,可以通过自定义组件来实现。 对于自定义组件,我们可以使用Form.create方法来创建一个高阶组件。在自定义组件中,我们可以通过getFieldDecorator方法来包装我们的自定义组件,实现表单验证的功能。 在包装自定义组件,我们可以使用rules参数来定义验证规则。比如,我们可以通过required:true来指定该字段为必填项,通过message参数来指定验证不通过的错误提示信息。除此之外,我们还可以自定义其他验证规则,比如验证正则表达式、长度范围等。 在自定义组件中,可以通过this.props.form.getFieldError来获取某个字段的验证错误信息,通过this.props.form.isFieldValidating来判断某个字段是否正在进行验证,通过this.props.form.validateFields来触发表单验证。 同,我们还可以使用validateTrigger参数来指定触发表单验证机,默认是onChange事件。比如,我们可以将validateTrigger设置为onBlur,表示在失去焦点进行表单验证。 总结来说,ant-design提供了一系列的API来实现表单验证功能,通过自定义组件的方式可以很方便地实现对自定义组件验证。开发者可以根据自己的需求灵活使用这些API来完成表单验证的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值