Redux form validation runs after onChange handler function

≡放荡痞女 提交于 2020-01-06 08:44:22

问题


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?


回答1:


Validation can only run after some fields have changed and this is why the first time _onImagePreviewChange is called with an invalid value, there are still no validation errors (as you said, validation is one step behind).

I would suggest to use componentWillReceiveProps method and within this method access the next and the current validation errors, check if some error was fixed or generated and take the actions you need to take. For example:

 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', '');
      }
    }
  }


来源:https://stackoverflow.com/questions/49936192/redux-form-validation-runs-after-onchange-handler-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!