本文简单分析了下 Form 组件的特点,以及定制化输入组件的封装技巧,希望对大家有所帮助。
antd Form 示例代码
import React from 'react'
import { Form, Input } from 'antd'
class FormDemo extends React.Component {
  
  submit = () => {
    const { form } = this.props
    form.validateFields((err, values) => {
      console.log(err, values)
    })
  }
  render() {
    const { form } = this.props
    return (
      <Form onSubmit={this.submit}>
        <Form.Item>
          {form.getFiledDecorator('userName', { initialValue: 'abc' })(
            <Input />
          )}
        </Form.Item>
        <Form.Item>
          <Button type="submit" >submit</Button>
        </Form.Item>
      </Form>
    )    
  }
}
export default Form.create()(FormDemo)
分析
Form.create() 返回一个HOC,将内部创建的 form 对象通过 props 传递给 FormDemo 组件,form 提供的 getFiledDecorator api从用法上看也是一个HOC,通过该api包装后的 Input 组件已经和 FormDemo 上层的HOC双向绑定,我们可以通过 form.validateFields 做表单域校验,获取表单值等操作。
实际上 form.getFiledDecorator() 返回的HOC给包裹的组件设置了 value 和 onChange 两个props,顶层HOC在提供的 onChange 内部劫持组件的输入变化,保存状态,同步 value,从而实现双向绑定。
扩展
经过分析,实际上 form.getFiledDecorator 包裹的组件不一定非得是 antd 提供的输入组件,我们自己也可以封装针对特定业务场景使用的复杂组件,只要在组件内部绑定来自HOC的 value 以及触发来自HOC的 onChange 事件,即可实现和 form 的双向绑定,从而充分利用 Form 组件的特性。