做單頁應用,不管是用Vue還是React,或者其他,有一個重要的原則,就是:組件重用。
既然組件可以重用,那么當添加一個信息,和修改該信息的布局必然是一致的,這時候,最好的方法自然是利用同一個組件,在添加信息的時候,默認值為空,在修改的時候,默認值為后台獲取到的數據。
看一個基礎頁面:
這是一個添加企業信息的頁面,這里利用antd的form繪制了一個基礎組件。到后來,需要修改企業信息的時候,發現布局部分完全一樣,那么必然是繼續利用該組件,只是此時需要傳遞props過來,以使得組件能夠自動添加默認數據。
平常,當props變化,我們重新組織頁面數據時候,經常使用的是componentWillReceiveProps這一生命周期函數,在其內部,進行數據的組織。
那么根據經驗,此時,我們在獲取到props值之后,進行數據填充。
componentWillReceiveProps(nextProps){ ...// 代碼省略 this.props.form.setFieldsValue(setFieldsValue.data) }
可是,當我們回過頭看一下antd的文檔的時候,會發現一個令人崩潰的事實。
會導致死循環,這就尷尬了,那么怎么解決初始值呢?
繼續查看文檔:
這不就是正好是我們當前出現困局的原因么!數據存在上層組件,需要傳遞過來,那么下面的事情就是怎么使用mapPropsToFields的問題了。繼續看文檔,發現mapPropsToFields居然是Form.create(options)中options的配置項。那不就得了,配唄!可是我們是不是有一個疑惑,配完之后,怎么應用到組件當中呢?
尷尬的是,無論如何我們都沒有再文檔中看到怎么應用到組件當中。只有一個簡單的示例:
mapPropsToFields(props) { return { username: Form.createFormField({ ...props.username, value: props.username.value, }), }; }
如果不仔細去扒拉扒拉的話,跟本不明白這個示例是個什么意思。
通過多次試驗,發現mapPropsToFields的返回對象的key值,其實就是我們在組件當中利用getFieldDecorator設置的關鍵字,只要配置正確,不需要額外的應用,配置完,antd會幫我們應用到組件當中。那我們就寫一個具體的例子。
export default Form.create({ mapPropsToFields (props) { ... //省略代碼 return props.auth ? { ownerNature: Form.createFormField({ value: props.auth.ownerNature }), ownerName: Form.createFormField({ value: props.auth.ownerName }), cidNumber: Form.createFormField({ value: props.auth.cidNumber }), registeredCapital: Form.createFormField({ value: props.auth.registeredCapital }) } : {} } })(componentName)
這里多一步三目運算是因為當我們在添加企業信息的時候,是沒有初始值的,如果不返回空對象的話,組件內部就報錯了。這里的‘ownerNature’, 'ownerName', 'cidNumber', 'registeredCapital',甚至更多,都是在render函數里面,通過getFieldDecorator定義的,必須value關鍵詞存儲其真實的數據。
至此,該Form表單算是可以真正的重用了。說實話,相比較而言,這里似乎比起Vue的v-model設計的數據雙向綁定復雜多了。
但是,這時候,如果頁面上有重置按鈕的話,那么還得注意,當修改信息的時候,不是直接resetFieldsValue,而是需要通知父組件重新請求數據,以達到恢復默認數據的目的。