我的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],
// ...
});
跑龙套/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
感谢@lewiscowper,他在一些JavaScript Slack上提出了这个解决方案。
由于输入是一个文本字段,因此如果呈现了输入,则该值将以空字符串的形式出现。
所以如果value
是null
/undefined
,我们可以跳过对字段的验证,因为我们知道它没有渲染。
为了避免验证器的误报用法,我将其重命名为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.';
}
}
最后,我认为一个完全排除验证器的解决方案——并且不使验证器的逻辑和使用复杂化——会好得多,但目前这是可行的。
很高兴接受更好的答案。
编辑:您还必须确保,在optional-field-render场景中,您也将其值触发为空字符串。在它被触摸之前,它的值通过验证器作为null。
MyForm.js
componentWillReceiveProps(nextProps) {
const { values, fields, isGuestOrder } = this.props;
if (isGuestOrder && values.email == null) {
fields.email.onChange('');
}
}
如果你想考虑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>
被卸载,该字段的验证将被重置。