使用react-validation-mixin验证redux-form

时间:2018-08-23 13:38:09

标签: reactjs validation redux redux-form joi

我以前使用Joireact-validation-mixin编写了一个表单,并且运行良好。

现在我们的团队决定从旧平台迁移,现在我们将reduxredux-form用于新表单。

我想实现的是将旧的验证系统保留在redux-form之内。

所以基本上验证部分是:

import Joi from 'joi';
import validation from 'react-validation-mixin';
import strategy from 'joi-validation-strategy';
import classnames from 'classnames';

class Form extends Component {
  constructor(props) {
    super(props);

    this.validatorTypes = {
      screenName: Joi.string().label('Screen Name'),
      ...
    };

    this.getValidatorData = this.getValidatorData.bind(this);
    this.renderHelpText = this.renderHelpText.bind(this);
    this.getClasses = this.getClasses.bind(this);
    this.onChange = this.onChange.bind(this);
  }

  onChange(field) {
    return (event) => {
      const { value } = event.target;
      this.props.updateField(field, value);
    };
  }

  getValidatorData() {
    return this.props;
  }

  getClasses(field) {
    const { isValid } = this.props;
    return classnames({
      'form-group': true,
      'has-error': !isValid(field),
    });
  }

  renderHelpText(message) {
    return (
      <span className="validation-error-message">{message}</span>
    );
  }

  render() {
    return (
      ...
    );
  }
}

export default validation(strategy)(Form);

添加redux-form后,我们的导出更改为:

export default connect(
  state => ({
    initialValues: state.initialValues,
  }),
)(reduxForm({
  form: 'form',
})(Form));

我看到redux-form接受一个名为validate的属性,在其中我尝试传递validation(strategy),但它只会产生错误...

我也尝试将包括它的出口链接起来,但是根本不起作用...

问题是,如何在使用react-validation-mixin的同时使用旧的Joi策略和redux-form来验证表单?

谢谢

1 个答案:

答案 0 :(得分:0)

这似乎不是一个完全容易的解决方法,但是您可以通过使用Joi作为验证的基础来最小化重构的影响。由于Joi验证是异步的,因此您可以使用async validation from redux-forms。看起来像这样:

import Joi from 'joi';
import strategy from 'joi-validation-strategy';
...

class Form extends Component {
   ...
}

//ideally put this in a utility file so you can use it anywhere you have form validation
const asyncJoiValidationWrapper = (schema) => {
   return (reduxFormValues) => {
      strategy().validate(reduxFormValues, schema, {}, errors => {

         //joi validation errors should be in the error format redux-forms needs
         //i.e. {screenName: 'Screen Name is not valid'}
         throw errors;
      });
   }
}  

//take this out of your constructor
const validatorTypes = {
  screenName: Joi.string().label('Screen Name'),
  ...
};

export default connect(
   state => ({
      initialValues: state.initialValues,
}),
)(reduxForm({
   form: 'form',
   asyncValidate: asyncJoiValidationWrapper(validatorTypes)
})(Form));