I have the following redux form:
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));
I want to have access to the field-level errors of the form inside _onImagePreviewChange
, with inputErrors
I set inside mapStateToProps
.
The problem is that the validation functions runs after onChange
handler function. Therefore the error message is always stale. For example, if user select a file of disallowed type, the message would be undefined
, the next time if user selects an file of allowed type, this time it wouldn't be undefined
as an error was assigned to it in the previous step.
Why does this happen and how should I fix it?