1. 程式人生 > 實用技巧 >React 封裝Form表單元件

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>
            )
        }
    }
}

總結

對於該高階方法,使用起來還是比較容易,這種方法在專案當中很多會遇到,我們專案中的簡訊驗證碼就多處用到,於是就自己封裝了一個高階元件,還是比較好用。

希望對您有幫助,感謝您的點贊,謝謝您的支援。