本文完整示例代码点击这里>>
0 异常场景
可能很多人和我一样在使用React + Ant Design开发项目时都曾遇到过这样一个场景:
首先,使用无状态方式自定义城市选择组件CitySelect
// CitySelect.js
import React from 'react'
import { observer } from 'mobx-react'
import { Select } from 'antd'
const { Option } = Select
const CitySelect = observer((props) => {
return (
<Select
showSearch
allowClear
style={{ width: 200 }}
placeholder="Select a city"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
<Option value="SH">上海</Option>
<Option value="BJ">北京</Option>
<Option value="SZ">深圳</Option>
<Option value="XIAN">西安</Option>
</Select>
)
})
export default CitySelect
其次,在UserInfoForm中引用自定义组件CitySelect
当点击提交按钮时,因Form没有获取到对应自定义组件的值,从而报错,报错信息如下图:
怎样才能使得Form.Item 包裹一个第三方组件或者自定义组件时,在点击submit时可以获取到对应组件的值呢?
1 解决方案
考虑到在开发中存在class和无状态两种组件书写方式,所以本文也会分别从这两种写法出发去寻找对应的解决方案。
1.1 无状态组件
思路:Antd的Form有个设置Form.Item值的方法:props.form.setFieldsValue({ key: value }),我们可以通过给自定义组件传入一个callback函数——> 在自定义组件中将值传给callback——> 通过callback设置Form.Item的值。
实现:
在UserInfoForm组件中调用自定义组件CitySelect时添加onSelect的callback函数
在自定义组件CitySelect中添加{...props}来接收callback函数
此时再次点击提交按钮时,便可成功获取自定义组件的值。
1.2 class组件
方案一:添加callback
首先,用class方式完成城市选择的组件CitySelectClass,代码如下:
// CitySelectClass.js
import React, { Component } from 'react'
import { Select } from 'antd'
const { Option } = Select
class CitySelectClass extends Component {
constructor(props) {
super(props)
}
handleSelect = (value) => {
const { callback } = this.props
callback(value)
}
render() {
return (
<Select
showSearch
allowClear
style={{ width: 200 }}
placeholder="Select a city"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
onSelect={value => this.handleSelect(value)}
>
<Option value="SH">上海</Option>
<Option value="BJ">北京</Option>
<Option value="SZ">深圳</Option>
<Option value="XIAN">西安</Option>
</Select>
)
}
}
export default CitySelectClass在UserInfoFormClass组件中调用自定义组件CitySelectClass,并传入回调函数(此方案类似于无状态组件的解决方案)
方案二:this.props.onChange()
定义省份选择组件StateSelectClass
// StateSelectClass.js
import React, { Component } from 'react'
import { Select } from 'antd'
const { Option } = Select
class StateSelectClass extends Component {
constructor(props) {
super(props)
}
handleSelect = (value) => {
const { onChange } = this.props
onChange(value)
}
render() {
return (
<Select
showSearch
allowClear
style={{ width: 200 }}
placeholder="Select a state"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
onSelect={value => this.handleSelect(value)}
>
<Option value="GZ">广州</Option>
<Option value="SC">四川</Option>
<Option value="YN">云南</Option>
<Option value="SHANXI">陕西</Option>
</Select>
)
}
}
export default StateSelectClass在UserInfoFormClass组件中调用组件StateSelectClass