1. Field packaging encapsulated in Antd form:

Here is a simple review of the entire implementation process of the train of thought, for the convenience of future review:

  1. MFormCreateComponents as decorators, wrappedMForm
  2. By deconstructing the assignmentconst {getFieldDecorator} = this.props.form;To obtain theMFromCreateThe passedForm objects (key-value pairs whose values are functions)
  3. getFieldDecoratorThe function is aHigher-order functions, the returned function receives oneJsx
    1. React.cloneElement(): clone and return a new oneReactElement(Inner child elements are also cloned), receiveThree parameters
    2. Parameter ①: React element for clone parent (mandatory)
    3. (2) : Add new props for the React element, or overwrite some or all of the props cloned from the parent. (optional)
    4. Parameter ③: Add new children to the React element, replacing the cloned children from the parent
  4. And then execute toonChangeThe event
  5. Then, inonChangeevent-boundhandleChangeChange in methodThe state status value
  6. insetStateThe second argument of the function argument validates the value of the latest modification
// MformCreate.js
import React, {Component} from 'react';

const MFormCreate = Comp= >{
    return class extends Component{
       constructor(props) {
           super(props);
           this.options = {};// The option value of each field does not change to affect component re-rendering
           this.state = {}; // Change the value of each field to trigger the check function
           this.form  = this.form.bind(this);
           this.getFieldDecorator = this.getFieldDecorator.bind(this);
           this.handleChange = this.handleChange.bind(this);
           this.validateFiled = this.validateFiled.bind(this);
       }
       // Handle input events for form items
       handleChange(e){
            const {name,value} = e.target;
            console.log("I am the name:",name,"I am worth it",value);
            this.setState({
              [name]:value
            },() = >{
                //🚀 verify each field after setting
                this.validateFiled(name); })}// 🌟 validation (rementioned below)
       validateFiled(filedName){
            console.log("Checked.",filedName);
       }
       // 🚀 getFieldDecorator returns a function
       getFieldDecorator(filedName,options){
           // Set the configuration of field options
           this.options[filedName] = options;
           return (Jsx) = >{
                //🚀 uses a more API approach here
               return (
                   <div>{// Two arguments: ① The element to clone; (2) the object attribute the React. CloneElement (Jsx, {name: filedName, / / controls the name value: this. The state [filedName] | | "", / / controls the value of the onChange: enclosing handleChange})}</div>)}}//🚀 where the form function returns an object composed of functions. If there is any subsequent addition, expand the returned object
       form(){
           return({getFieldDecorator:this.getFieldDecorator
               }
           )
       }
       render() {
            return (
                <Comp {. this.props} form = {this.form()}> </Comp>)}}}Copy the code
//MForm.js

import React, {Component} from 'react';
import MFormCreate form "./Compontent";

@MFormCreate
class MForm extends Component {
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }
    handleSubmit(){
       // Verify that each field is correct
    }
    render() {
        const {getFieldDecorator} = this.props.form;
        return (
            <div>{getFieldDecorator("username",{rules:[{required:true, message:" username"}]})(<input type="text"/>)} {getFieldDecorator("password",{rules:[{required:true, message:" password is required "}]})(<input type="password"/>)
                }
                {/*<input type="text"/>* /} {/ *<input type="password"/>* /}<input type="button" value="Login" onClick={this.handleSubmit}/>
            </div>); }}export default MForm;
Copy the code

2. Verification of individual items of the form:

  1. getFieldDecoratorIn the functionthis.options[filedName] = options;Complete the assignment to this.options
  2. handleChangePass the input value as a parameter tovalidateFiledTo verify
  3. validateFiledFunction of thethis.optionsDeconstruct and then use the rules to judge.
    / / validateFiled function
/ /...
       validateFiled(filedName){
            console.log("Checked.",filedName);
            const {rules} = this.options[filedName];
            const ret = rules.some(rule= >{
                //🚀 Verification is required if required is true
                if(rule.required){
                    // If the input field has no value, set the rule-message text displayed to prompt
                    if(!this.state[filedName]){
                       this.setState({
                           [filedName + "Message"]:rule.message
                       })
                        return true; // Verification failure returns true}}})if(! ret){this.setState({
                   [filedName + "Message"] :""})}return! ret;// Verify success returns false
       }
/ /...
Copy the code

3. Implementation method of form submission button verification:

  1. fromhanldeSubmitThe return form object is newly addedvalidateFieldsMethod to validate the submit button
  2. throughObject.keys(this.options)Once you have the desired array of keys, check each item individually —validateFiled
  3. Finally, the verification result is passedcallbackThe callback function is passed back
  4. trueEject successfultips.falseEject failedtips
//MFromCreate.js
import React, {Component} from 'react';

const MFormCreate = Comp= >{
    return class extends Component{
       constructor(props) {
           super(props);
           this.options = {};// The option value of each field does not change to affect component re-rendering
           this.state = {}; // Change the value of each field to trigger the check function
           this.form  = this.form.bind(this);
           this.getFieldDecorator = this.getFieldDecorator.bind(this);
           this.handleChange = this.handleChange.bind(this);
           this.validateFiled = this.validateFiled.bind(this);
           this.validateFileds = this.validateFileds.bind(this);
       }
       // Handle input events for form items
       handleChange(e){
            const {name,value} = e.target;
            console.log("I am the name:",name,"I am worth it",value);
            //setState is asynchronous
            this.setState({
              [name]:value
            },() = >{
                //🚀 verify each field after setting
                this.validateFiled(name); })}//🚀 single item verification
       validateFiled(filedName){
            console.log("Checked.",filedName);
            const {rules} = this.options[filedName];
            const ret = rules.some(rule= >{
                //🚀 Verification is required if required is true
                if(rule.required){
                    // If the input field has no value, set the rule-message text displayed to prompt
                    if(!this.state[filedName]){
                       this.setState({
                           [filedName + "Message"]:rule.message
                       })
                        return true; }}})if(! ret){this.setState({
                   [filedName + "Message"] :""})}return! ret; }// 🚀 form submit button validation
        validateFileds(callback){
            // Select the value of each field and verify each field
            console.log("Test".Object.keys(this.options))
            const rets = Object.keys(this.options).map((filedName) = >{
                    return this.validateFiled(filedName);
                })
            // Use the every method of the array, if all the single item checks are true, then the check passes
            const res = rets.every(v= >v===true);
            callback(res);
        }
       //getFieldDecorator returns a function
       getFieldDecorator(filedName,options){
           // Set the configuration of field options
           this.options[filedName] = options;
           return (Jsx) = >{
                //🚀 uses a more API approach here
               return (
                   <div>{// Two arguments: ① The element to clone; (2) the object attribute the React. CloneElement (Jsx, {name: filedName, / / controls the name value: this. The state [filedName] | | "", / / control the value of the onChange: enclosing handleChange})} {this. The state [filedName + "Message"] && (<p style={{color:'red'}} >{this.state[filedName + "Message"]}</p>)}</div>)}}// The form function is called and returns an object composed of functions
       form(){
           return({getFieldDecorator:this.getFieldDecorator,
                   validateFields:this.validateFileds 
               }
           )
       }
       render() {
            return (
                <Comp {. this.props} form = {this.form()}> </Comp>)}}}Copy the code
/ / MForm. Js validation
import React, {Component} from 'react';
import MFormCreate form "./Compontent";

@MFormCreate
class MForm extends Component {
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }
    handleSubmit(){
       // Verify that each field is correct
        this.props.form.validateFields((isValid) = >{
            if(isValid){
                alert("Verification successful ~!")}else{
                alert("Verification failed, please re-enter")}}}render() {
        const {getFieldDecorator} = this.props.form;
        return (
            <div>{getFieldDecorator("username",{rules:[{required:true, message:" username"}]})(<input type="text"/>)} {getFieldDecorator("password",{rules:[{required:true, message:" password is required "}]})(<input type="password"/>)
                }
                {/*<input type="text"/>* /} {/ *<input type="password"/>* /}<input type="button" value="Login" onClick={this.handleSubmit}/>
            </div>); }}export default MForm;
Copy the code

The use of the callback function is really bad. Scrape ()