我有以下redux形式:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm, getFormSyncErrors } from 'redux-form';
import { createExpense } from '../../actions';
import { validateName, validateImage } from '../../helpers/expense_utils';
import { renderInputField, validate, renderTextAreaField, renderDropzoneField } from '../../helpers/form_utils';
const validators = [
{
field: 'title',
validator: validateName
},
{
field: 'description',
validator: validateDescription
},
{
field: 'amount',
validator: validateAmount
},
{
field: 'image',
validator: validateImage
}
];
class NewExpense extends Component {
constructor(props) {
super(props);
this.state = {
error: undefined,
imagePreviewUrl: undefined
};
}
_onSubmit = values => {
let formData = new FormData();
formData.append('title', values.title);
formData.append('description', values.description);
formData.append('amount', values.amount);
formData.append('file', values.image[0]);
this.props.createExpense(formData, this.props.groupId, () => this.props.onClose(), error => this.setState({error: error}));
}
_onImagePreviewChange = files => {
//this.props.inputErrors.image is one step behind
this.setState({
imagePreviewUrl: files[0].preview
});
}
render() {
const { handleSubmit } = this.props;
const { imagePreviewUrl } = this.state;
return (
<div>
<form onSubmit={ handleSubmit(this._onSubmit.bind(this)) }>
<Field name="title" label="Name" type="text" component={ renderInputField }/>
<Field onChange={this._onImagePreviewChange.bind(this)} previewUrl={ imagePreviewUrl } name="image" label="Image" component={ renderDropzoneField } />
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
</form>
{ this.state.error ? <span>{this.state.error}</span> : <noscript/> }
</div>
);
}
}
export default connect(state => ({
inputErrors: getFormSyncErrors('NewExpense')(state)
}), { createExpense })(reduxForm({
validate,
form:'NewExpense',
validators
})(NewExpense));
我希望能够访问_onImagePreviewChange
内的表单的字段级错误,并在inputErrors
内设置mapStateToProps
。
问题是验证函数在onChange
处理函数之后运行。因此,错误消息始终是陈旧的。例如,如果用户选择了不允许类型的文件,则该消息将为undefined
,下次如果用户选择允许类型的文件,则此时它不会undefined
为 register_post_status( 'wc-arrival-shipment', array(
'label' => 'Shipped but not paid',
'public' => false,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop( 'Shipped but not paid<span class="count">(%s)</span>', 'Shipped but not paid <span class="count">(%s)</span>' )
) );
在上一步中为其分配了错误。
为什么会发生这种情况,我应该如何解决?
答案 0 :(得分:1)
验证只能在某些字段更改后运行,这就是为什么第一次使用无效值调用_onImagePreviewChange
时,仍然没有验证错误(正如您所说,验证落后一步)。 / p>
我建议使用componentWillReceiveProps
方法,并在此方法中访问下一个和当前的验证错误,检查是否已修复或生成某些错误,并采取您需要采取的操作。例如:
componentWillReceiveProps(newProps) {
// here newProps.inputErrors is up-to-date while this.props.inputErrors is the current
if (newProps.inputErrors && newProps.inputErrors !== this.props.inputErrors) {
console.log(newProps.inputErrors); // up-to-date input errors
if (newProps.inputErrors.image) {
// clear invalid image field if you need to
this.props.change('image', '');
}
}
}