redux-form:如何动态排除一个同步验证器?

时间:2016-08-10 11:07:45

标签: reactjs redux redux-form

我的redux-form修饰表单组件有条件地有一个email字段,具体取决于我的redux状态(取决于用户是否是来宾。)

我只想在该字段存在时进行同步验证(有条件地呈现)。目前,表单的验证程序包含email字段验证程序,并且此验证程序即使已从字段排除表格,在render

期间 当我将验证器作为参数传递给redux-form装饰器时,当我“实例化”表单的验证器时,状态是未知的。所以我目前无法决定是否在这两个地方都包含email字段验证器。

根据状态,在“运行时”/“验证时间”动态包含/排除单个字段的redux-form验证器的最佳方法是什么?

MyForm.js

import validate from './MyFormValidator';

// [form class whose render optionally shows the email component]

export default reduxForm(
  {
    form: 'myForm',
    fields,
    validate
  }
)(MyForm)

MyFormValidator.js

import {createValidator, required, email} from '../../utils/validation';

export default createValidator({
  email: [email],
  country: [required],
  // ...
});

utils的/ validation.js

export function email(value) {
  const emailRegex = /.../i;
  if (!emailRegex.exec(value)) {
    return 'Please provide a valid email address.';
  }
}

export function required(value, message) {
  if (isEmpty(value)) {
    return message || 'Required.';
  }
}

export function createValidator(rules) {
  return (data = {}) => {
    const errors = {};
    Object.keys(rules).forEach((key) => {
      const rule = join([].concat(rules[key]));
      const error = rule(data[key], data);
      if (error) {
        errors[key] = error;
      }
    });
    return errors;
  };
}

我的同步验证是在此实现之后建模的,链接到4.2.0 redux-form文档(我正在使用5.3.1):https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/utils/validation.js

2 个答案:

答案 0 :(得分:2)

感谢@lewiscowper在一些JavaScript Slack上提出了这个解决方案。

由于输入是文本字段,如果输入已呈现,则值将作为空字符串传递。

因此,如果valuenull / undefined,我们可以跳过该字段的验证,因为我们知道它没有呈现。 < / p>

为了避免验证器的误报用法,我将其重命名为emailUnlessNull

export function emailUnlessNull(value) {
  // Don't validate the text field if it's value is undefined (if it wasn't included in the form)
  if (value == null) {
    return;
  }
  const emailRegex = /.../i;
  if (!emailRegex.exec(value)) {
    return 'Please provide a valid email address.';
  }
}

最后,我认为一个完全排除验证者的解决方案 - 并不会使验证者的逻辑和它的用法复杂化 - 会好得多,但是现在这很有效。

很高兴接受更好的答案。

修改

您还必须确保在可选字段渲染方案中,您还可以将其值触发为空字符串。在触摸它之前,它的值通过验证器作为null。

<强> MyForm.js

componentWillReceiveProps(nextProps) {
  const { values, fields, isGuestOrder } = this.props;

  if (isGuestOrder && values.email == null) {
    fields.email.onChange('');
  }
}

答案 1 :(得分:1)

如果你想考虑React-Redux-Form,这已经是内置的:

import { Field } from 'react-redux-form';
import { required, email } from '../../utils/validation';

// inside render():
<Field model="user.email"
  errors={{ email }}
/>

会发生两件事:

  • 错误验证器(error)将在每次更改时运行。您可以设置validateOn="blur"来修改此行为。
  • 只有在呈现<Field>时才会进行验证。如果已卸载<Field>,则将为该字段重置验证。