日日行,不怕千万里

React 封装Form表单组件

图片

使用前提:

主要是仿照 antd 组件中的form表单组件,通过组件包装之后组件提供一些方法导出一些方法,以及导出相应的值。Antd-Form

类似于这样的组件,⽤Form.create()的⽅式实现:
      getFieldDecorator: ⽤于和表单进⾏双向绑定
      getFieldsValue:获取⼀组输⼊控件的值,如不传⼊参数,则获取全部组件的值
      getFieldValue: 获取⼀个输⼊控件的值
      validateFields:校验并获取⼀组输⼊域的值与 Error,若fieldNames 参数为空,则校验全部组件

对于以上介绍,我们言归正传,对组件封装:

import React from 'react';
import { Input } from 'antd'; 
// 使用该方法的组件
@FormCreate
class FormComp extends React.Component {
    render() {
        const { getFieldDecorator } = this.props;
        return (
            <div>
                {getFieldDecorator('name',{
                    rules: [{required: true, message: "请输入姓名"}]
                })(
                    <Input placeholder="请输入姓名"/>
                )}
                {getFieldDecorator('password', {
                     rules: [{required: true, message: "请输入密码"}]
                })(
                    <Input placeholder="请输入密码"/>
                )}
                <Button>提交</Button>
            </div>
        )
    }
}

export default FormComp ;

封装的高阶方法:

import React from 'react';
const FormCreate = (comp) => {
    return class extends React.Component{
        constructor(props){
            super(props);
            this.state={}
            this.options = {};
        }

        handleChange = (e) => {
            const { name, value } = e.target;
            this.setState({[name]: value});
        }

        getFieldDecorator = (filed, option) => {
            this.options[filed] = option;
            return (Comp) => {
                React.cloneElement(Comp, {
                    name: filed,
                    value: this.state.filed||'',
                    onChange: this.handleChange
                })
            }
        }

        getFieldsValue = () => {
            return {...this.state};
        }

        getFieldValue = (filed) => {
            return this.state[filed];
        }

        validateFields = callback => {
            let errors = {};
            const state = {...this.state};
            for(let filed in this.options){
                if(state[filed] === undefined){
                    errors[filed] = "error"
                }
            }
            if (JSON.stringify(errors) == '{}') {
                callback(undefined, state);
            } else {
                callback(errors, state);
            }
        }
        render() {
            return (
                <div>
                    <Comp 
                        {...this.props}
                        getFieldDecorator={this.getFieldDecorator}
                        getFieldsValue={this.getFieldsValue}
                        getFieldValue={this.getFieldsValue}
                        validateFields={this.validateFields}
                    />
                </div>
            )
        }
    }
}

总结

对于该高阶方法,使用起来还是比较容易,这种方法在项目当中很多会遇到,我们项目中的短信验证码就多处用到,于是就自己封装了一个高阶组件,还是比较好用。

希望对您有帮助,感谢您的点赞,谢谢您的支持。

posted @ 2020-12-21 20:23  GongXiaoZhu  阅读(1054)  评论(0编辑  收藏  举报