关于react.js:hoc实现表单组件的设计思路

44次阅读

共计 2941 个字符,预计需要花费 8 分钟才能阅读完成。

前言

通过模拟 rc-form 的实现思路,能够学习一下 hoc 的应用场景。

裸露 createForm() 函数

通过 createForm 函数,返回一个组件。该组件拓展了咱们的一些办法。

export function createForm(Cmp) {
return class extends Component {getFieldDecorator = () => {}
getFieldsValue = () => {}
getFieldValue = () => {}
setFieldValue = () => {}
validateFields = () => {}
form = () => {
return {
getFieldDecorator: this.getFieldDecorator,
getFieldValue: this.getFieldValue,
getFieldsValue: this.getFieldsValue,
setFieldValue: this.setFieldValue,
validateFields: this.validateFields,
}
}
render() {const form = getForm()
return <Cmp {...this.props} form={form} />
}
}
}

实现 getFieldDecorator

应用办法

<div>
{getFieldDecorator('username', {rules: { require: true, message: '请输出用户名'})(<input placeholder="请输出用户名" />)}
</div>

能够看出,该函数接管两个参数,第一个是字段名,第二个是它的规定。又接着返回了一个接管一个组件的函数,最终返回一个加工后的组件。当初咱们开始简略实现一下。

constructor(){
// ...
this.state = {}
this.options = {}}
getFieldDecorator = (fieldName, option) => InputCmp => {
// 保留数据和选项
if (this.state[fieldName] === undefined) this.setState({[fieldName]: '' })
this.options[fieldName] = option
// 返回一个解决后的组件
return React.cloneElement(InputCmp, {
name: fieldName,
value: this.state[fieldName],
onChange: this.handleChange,
})
}

定义 handleChange 事件

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

实现 getFieldValue

间接把 state 的数据返回即可

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

实现 getFieldsValue

通过传进来的名字,返回对应的数据

getFieldValue = name => {return this.state[name]
}

实现 setFieldValue

间接将传进来的数据合并起来即可

setFieldValue = state => {this.setState(state)
}

实现 validateFields

该办法接管一个回调函数,通过遍历 options 的规定,在判断相应的值,返回谬误数据以及 state 的数据

validateFields = callback => {const err = []
for (let fieldName in this.options) {const rules = this.options[fieldName]?.rules
const value = 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})
}
}

最终代码

import React, {Component} from 'react'
export function createForm(Cmp) {
return class extends Component {constructor(props) {super(props)
this.state = {}
this.options = {}}
handleChange = e => {const { name, value} = e.target
this.setState({[name]: value })
}
validateFields = callback => {const err = []
for (let fieldName in this.options) {const rules = this.options[fieldName]?.rules
if (rules && 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] = option
if (this.state[fieldName] === undefined) this.setState({[fieldName]: '' })
return React.cloneElement(InputCmp, {
name: fieldName,
value: this.state[fieldName],
onChange: this.handleChange,
})
}
getFieldValue = name => {return this.state[name]
}
getFieldsValue = () => {return { ...this.state}
}
setFieldValue = state => {this.setState(state)
}
getForm = () => {
return {
getFieldDecorator: this.getFieldDecorator,
getFieldValue: this.getFieldValue,
getFieldsValue: this.getFieldsValue,
setFieldValue: this.setFieldValue,
validateFields: this.validateFields,
}
}
render() {const form = this.getForm()
return <Cmp {...this.props} form={form} />
}
}
}

正文完
 0