Ant Design的表单onChange阶段不更新踩坑,以及修改表单值方法
新项目中使用antd-pro框架,所以接下来会写一些关于antd-pro的踩坑
在写项目中,中有一个需求是在某个表单元素变化时,出发表单提交,但是发现一个问题是,将方法绑定onChange的时候发现此时通过表单方法获取的值还没有更新,不知道这个属于一个bug,还是在这个阶段本来就没有变更表单的values ,所以我是在onChange绑定的方法中手动将e.target.value的值赋到表单中,但是不知道有没有其他优雅的解决方式
//radio绑定了切换状态,触发事件
{getFieldDecorator('isEnabled')(
<Radio.Group buttonStyle="solid" onChange={this.changeStatus}>
<Radio.Button >全部</Radio.Button>
<Radio.Button value={1}>启用</Radio.Button>
<Radio.Button value={0}>禁用</Radio.Button>
</Radio.Group>
)}
//方法部分
changeStatus = e => {
const { formValues } = this.state;
const { form } = this.props;
this.setState({
formValues: { ...formValues,status:e.target.value} //手动赋值
});
form.setFieldsValue({status:e.target.value})
this.handleSearch() //调用真正的方法
}2019/2/17 更新
onChange阶段为什么表单还没更新
通过查看http:///entry/348216这篇文章,我理解到为什么onChange阶段表单值为什么还没有更新。
这里直接看ant design的源码
onChange方法,是onCollect 被 bind 后的方法,我们查看源码中的 onCollect
onCollect(name_, action, ...args) {
//onChange方法真正在onCollectCommon中执行
const { name, field, fieldMeta } = this.onCollectCommon(name_, action, args);
const { validate } = fieldMeta;
const newField = {
...field,
dirty: hasRules(validate),
};
//这里进行了最新的值的设置
this.setFields({
[name]: newField,
});
},下面onCollectCommon方法的源码
// action实际上是trigger 默认是onChange
onCollectCommon(name, action, args) {
const fieldMeta = this.fieldsStore.getFieldMeta(name);
//下面才是真正onChange方法的执行
if (fieldMeta[action]) {
// onchange getFieldProps中写法
fieldMeta[action](...args);
} else if (fieldMeta.originalProps && fieldMeta.originalProps[action]) {
// onchange getFieldDecorator中的写法
fieldMeta.originalProps[action](...args);
}
// some code...
// onchange同步执行完后再执下面代码,下面的返回并不会受onchange同步执行的影响
return ({ name, field: { ...field, value, touched: true }, fieldMeta });
},从上面我们可以看出设置最新值setFields是在onChange之后,同时我们也可以猜想到,如果在onChange中使用form.setFieldsValue(...)这样的方法最后会被onCollect中的setFields方法重新覆盖而无效,所以如果你想在onChange阶段修改值的话可以这样
setTimeout(() => {
setFieldsValue({ name: targetValues })
}, 0);当然在我最上面的代码中,没有使用setTimeout是因为我不需要修改表单,我只是为了在onChange阶段获得最新的值并提交表单。
修改表单的值
然而如果你单纯只是为了修改表单的值,而不是为了在onChange阶段获取最新值的话,不应该使用上面的方法,应该使用官方提供的normalize,这是专门用来提供修改表单获取的值的方法
...
normalizeAll = (value, prevValue = []) => {
if (value.indexOf('All') >= 0 && prevValue.indexOf('All') < 0) {
return ['All', 'Apple', 'Pear', 'Orange'];
}
if (value.indexOf('All') < 0 && prevValue.indexOf('All') >= 0) {
return [];
}
return value;
};
....
<FormItem>
{this.props.form.getFieldDecorator('fruits', {
normalize: this.normalizeAll,
})(<CheckboxGroup options={options} />)}
</FormItem>
















