在開發過程當中,表單組件是很是經常使用的組件之一。在antd中,我的傾向於使用getFieldDecorator
去建立formItem
。默認的input/select
等組件有時候不太能知足需求,因此就會須要自定義一些組件,傳遞給getFieldDecorator
。antd
假設咱們須要封裝一個能夠過濾遠程數據的組件,即antd
的select
組件的search
功能。這個組件會根據輸入去特定接口獲取數據,而後顯示出來,供用戶篩選。組件封裝以下async
// 務必使用class方式,若是使用function形式的話,沒法被getFieldDecorator使用
class ExampleSeach extends React.Component {
constructor(props) {
super(props)
this.state = {
value: '',
options: []
}
}
handleSearch = async (value) => {
if (value) {
// 加載遠程數據
let res = await fetchData()
this.setState({
options: res
})
} else {
this.setState({
options: []
})
}
}
handleChange = value => {
this.setState({
value: value
})
// 下面一行代碼是關鍵,在被getFieldDecorator包裝後,會綁定一個onChange事件,
// 接收的第一個參數將做爲當前formItem的value
this.props.onChange(value)
}
render() {
const opts = options.map(ele => <Option key={ele.value}>{ele.label}</Option>)
return (
<Select
showSearch
value={this.state.value}
defaultActiveFirstOption={false}
showArrow={false}
filterOption={false}
onSearch={this.handleSearch}
onChange={this.handleChange}
notFoundContent={null}
>
{opts}
</Select>
)
}
}
複製代碼
以上就實現了一個自定義的遠程過濾組件的封裝,能夠像用Input等組件同樣直接在getFieldDecorator
中使用了。fetch
若是想給該組件手動賦值(好比編輯某個數據的時候,表單元素默認已經有值了)this
// 1. 組件中添加生命週期
static getDerivedStateFromProps(nextProps, prevState) {
// 通過getFieldDecorator封裝之後,props會有value屬性,表明外部傳遞過來的值
if (nextProps.value !== prevState.value) {
return {
value: nextProps.value
}
}
return null
}
// 2. getFieldDecorator中使用的是,經過initialValue賦值
// 或者在表單建立完成後,使用setFields去給表單賦值,這樣都會觸發自定義組件的生命週期,從而改變組件的值
複製代碼
自定義一個表單元素組件,關鍵就是在組件中的數據變化的時候,去調用props.onChange事件,將組件的值傳遞到外面spa