当前位置: 首页 > Web前端 > JavaScript

hoc实现表单组件的设计思路

时间:2023-03-27 01:44:56 JavaScript

前言通过模仿rc-form的实现思路,可以学习到hoc的使用场景。通过返回组件的createForm函数公开createForm()函数。该组件扩展了我们的一些方法。导出函数createForm(Cmp){返回类扩展组件{getFieldDecorator=()=>{}getFieldsValue=()=>{}getFieldValue=()=>{}setFieldValue=()=>{}validateFields=()=>{}form=()=>{return{getFieldDecorator:this.getFieldDecorator,getFieldValue:this.getFieldValue,getFieldsValue:this.getFieldsValue,setFieldValue:this.setFieldValue,validateFields:this.validateFields,}}render(){constform=getForm()返回}}}使用方法

{getFieldDecorator('username',{rules:{require:true,message:'PleaseEntertheusername'})()}
可以看出这个函数接收两个参数,第一个是字段名,第二个是它的规则。然后它返回一个接收组件的函数,最后返回一个处理过的组件。现在让我们从一个简单的实现开始。constructor(){//...this.state={}this.options={}}getFieldDecorator=(fieldName,option)=>InputCmp=>{//保存数据和选项if(this.state[fieldName]===undefined)this.setState({[fieldName]:''})this.options[fieldName]=option//返回一个处理过的组件returnReact.cloneElement(InputCmp,{name:fieldName,value:this.state[fieldName],onChange:this.handleChange,})}定义handleChange事件handleChange=(e)=>{const{name,value}=e.targetthis.setState({[name]:value})}直接实现getFieldValue返回即可状态数据getFieldsValue=()=>{return{...this.state}}实现getFieldsValue传入name,返回对应的数据getFieldValue=name=>{returnthis.state[name]}实现setFieldValue直接组合传入的数据。setFieldValue=state=>{this.setState(state)}实现validateFields。此方法接收回调函数。通过遍历options的规则,判断对应的值,返回错误数据和状态数据validateFields=callback=>{consterr=[]for(letfieldNameinthis.options){construles=this.options[fieldName]?.规则constvalue=this.state[fieldName]if(rules&&rules.require&&rules.message&&!value){err.push({[fieldName]:rules.message})}}//判定err是否有数据if(err.length===0){callback(null,{...this.state})}else{callback(err,{...this.state})}}最终代码importReact,{Component}from'react'exportfunctioncreateForm(Cmp){returnclassextendsComponent{constructor(props){super(props)this.state={}this.options={}}handleChange=e=>{const{name,value}=e复制代码.targetthis.setState({[name]:value})}validateFields=callback=>{consterr=[]for(letfieldNameinthis.options){construles=this.options[fieldName]?.rulesif(规则&&rules.require&&rules.message&&!this.state[fieldName]){err.push({[fieldName]:rules.message,})}}if(err.length===0){callback(null,{...this.state})}else{callback(err,{...this.state})}}getFieldDecorator=(fieldName,option)=>InputCmp=>{this.options[fieldName]=optionif(this.state[fieldName]===undefined)this.setState({[fieldName]:''})returnReact.cloneElement(InputCmp,{name:fieldName,value:this.state[fieldName],onChange:this.handleChange,})}getFieldValue=name=>{returnthis.state[name]}getFieldsValue=()=>{返回{...this.state}}setFieldValue=state=>{this.setState(state)}getForm=()=>{返回{this.validateFields,}}仁der(){constform=this.getForm()返回}}}