目前專案中對錶單的使用較多,最近遇到了一個問題,大致描述:在表單域的onChange元件中無法使用setFields重置當前表單域的值.
- 發現問題:
class App extends React.Component {
handleChange = e => {
const val = e.target.value.toUpperCase();
this.props.form.setFieldsValue({
userName: val
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit}>
<Form.Item
labelCol={{ span: 5 }}
wrapperCol={{ span: 12 }}
label="字首"
>
{getFieldDecorator("userName")(
<Input onChange={this.handleChange} />
)}
</Form.Item>
</Form>
);
}
}
複製程式碼
- 進行嘗試:在
onChange
的回撥函式中利用setTimeout(func,0)
[1]進行非同步賦值,類似情況出現在onChange
回撥中利用form.getFieldsValue
無法實時取值時。rc-form
表單元件是通過setState
的方式,將表單項封裝為受控元件。在onChange
的回撥方法中,我們可以通過e.target.value
拿到最新的值,此時,rc-form
元件自身的賦值方法中並無法拿到這個最新的值,所以,進行同步並重新整理頁面值時,會把我們主動呼叫setFieldsValue
方法傳入setState中的值覆蓋掉,所以使用非同步賦值的方法,可以解決我們這裡出現的值覆蓋情況。
class App extends React.Component {
handleChange = e => {
const val = e.target.value.toUpperCase();
this.props.form.setFieldsValue({
prefix: val,
suffix: val + "2"
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit}>
<Form.Item {...formItemLayout} label="prefix">
{getFieldDecorator("prefix")(<Input onChange={this.handleChange} />)}
</Form.Item>
<Form.Item {...formItemLayout} label="suffix">
{getFieldDecorator("suffix")(<Input />)}
</Form.Item>
</Form>
);
}
}
複製程式碼
- 較之更優的方法-使用option.getValueFromEvent,進行賦值,相比之下,它更優雅而且不會造成二次渲染。
引數 | 說明 | 型別 | 預設值 |
---|---|---|---|
option.getValueFormEvent | 可以把onChange的引數轉化為控制元件的值(例如:Event) | func(...args) | e |
class App extends React.Component {
render() {
const { getFieldDecorator } = this.props.form;
const varsPrefixField = getFieldDecorator("prefix", {
getValueFromEvent: e => e.target.value.toUpperCase()
});
return (
<Form onSubmit={this.handleSubmit}>
<Form.Item {...formItemLayout}
label="字首"
>
{varsPrefixField(<Input />)}
</Form.Item>
</Form>
);
}
}
複製程式碼
備註:這裡的特殊情況出現在我們的表單域為自定義的InputGroup組合輸入框。
Refrence:
[1] “如果以0毫秒的超時時間來呼叫setTimeout(),那麼指定的函式不會立刻執行。相反,會把它放到佇列中,等到前面處於等待狀態的事件處理程式全部執行完成後,再“立即”呼叫它。”
摘錄來自: (美)David Flanagan. “JavaScript權威指南(原書第6版)”。 iBooks.