

组件的源码
下面看一下如何自己封装表单组件,这是一个最基础的表单使用例子:
1 import React, { PureComponent } from 'react'
2 import { Button, Form, Input, Radio } from 'antd'
3 import FormItem from 'components/FormItem'
4
5 const RadioGroup = Radio.Group
6 const options = [
7 { label: '男', value: 1 },
8 { label: '女', value: 2 },
9 ]
10
11 class Test extends PureComponent {
12 handleSubmit = (e) => {
13 e.preventDefault();
14
15 const { form: { validateFields } } = this.props;
16
17 validateFields((errors, values) => {
18 if (errors) {
19 return;
20 }
21 console.log(values)
22 })
23 }
24
25 render() {
26 const { form: { getFieldDecorator } } = this.props
27
28 const nameDecorator = getFieldDecorator('name')
29 const sexDecorator = getFieldDecorator('sex')
30
31 return (
32 <section>
33 <Form layout="horizontal" onSubmit={this.handleSubmit}>
34 <FormItem label="姓名">
35 {nameDecorator(<Input />)}
36 </FormItem>
37
38 <FormItem label="年龄">
39 {sexDecorator(<RadioGroup options={options} />)}
40 </FormItem>
41
42 <FormItem buttonsContainer>
43 <Button type="primary" size="default" htmlType="submit">提交</Button>
44 </FormItem>
45 </Form>
46 </section>
47 );
48 }
49 }
50
51 export default Form.create()(Test)现在需求需要我们实现多个姓名的提交,这时使用UI组件提供的表单便无法实现。
下面我们可以封装一个InputArrary组件:
1 import React, { PureComponent } from 'react'
2 import PropTypes from 'prop-types'
3 import { Button, Icon, Input } from 'antd'
4
5 import './index.scss'
6
7 class InputArray extends PureComponent {
8 constructor(props) {
9 super(props)
10 }
11
12 handleChange = index => {
13 const { value, onChange } = this.props
14 const newValue = [...value]
15
16 newValue[index] = target.value
17
18 onChange(newValue)
19 }
20
21 handleDelete = e => {
22 const target = e.currentTarget
23 const index = target.parentNode.parentNode.firstChild.dataset.index
24 const { value, onChange } = this.props
25 const newValue = [...value]
26
27 newValue.splice(Number(index), 1)
28
29 onChange(newValue)
30 }
31
32 handleAdd = () => {
33 const { value, onChange } = this.props
34 const newValue = [...value, '']
35
36 onChange(newValue)
37 }
38
39 render() {
40 const { value, ...others } = this.props
41
42 const closeBtn = <Icon type="close-circle" onClick={this.handleDelete} />
43
44 return (
45 <p className="input-array-component">
46 {value.map((v, i) => {
47 return (
48 <p key={i}>
49 <Input
50 {...others}
51 value={v}
52 suffix={closeBtn}
53 data-index={i}
54 onChange={() => this.handleChange(i)}
55 />
56 </p>
57 );
58 })}
59 <p>
60 <Button type="dashed" icon="plus" onClick={this.handleAdd}>添加</Button>
61 </p>
62 </p>
63 );
64 }
65 }
66
67 InputArray.defaultProps = {
68 value: []
69 }
70
71 export default InputArray这是我们就可以像引入Input组件一样引入InputArray组件实现了一组姓名的提交。
<FormItem label="姓名">{nameDecorator(<InputArray />)}
</FormItem组件主要使用的form提供getFieldDecorator方法,这个方法会向组件注入value参数,onChange方法,每次调用onChange方法都会去改变value,从而刷新整个组件。为什么会这样那,其实Ant Design 会在表单组件外层包裹一层组件,维护一个State值,每次onChange都是在改变外部state值,调用setState来刷新表单组件。
Upload组件使用中也遇到一个坑,Upload组件action上传地址参数也是必填参数,每次上传都会直接上传到服务器,不能和其它表单的数据一起提交,这时候我们也必须从新封装一个上传组件,同时因为存在文件或图片数据就不能使用json格式和后台进行交互,必须使用new FormData()的数据格式上传,也就是原生的表单的submit提交。
组件的源码
如果为你提供了一定的帮助,请点 start 支持一下
