2016-08-10 2 views
1

Мой redux-form оформленный вид компонента условно имеет email поле, в зависимости от моего Redux состояния (в зависимости от того или нет пользователь является гостем.)redux-form: Как я могу динамически исключить один валидатор синхронизации?

Я только хочу, чтобы синхронизировать, проверить это поле, когда он присутствует (условно rendered.) В настоящее время валидатор формы включает в себя валидатор поля email, и этот валидатор работает, даже если поле было исключено из формы, в течение render.

Когда я «экземпляр» валидатор формы, а и, когда я прохожу валидатор в качестве аргумента перевождь-формы декоратора, состояние не известно. Поэтому в настоящее время я не могу решить, следует ли включать в систему значение email в любом из этих мест.

Каков наилучший способ динамического включения/исключения проверки валидатора для одного поля в режиме «время выполнения»/«время проверки» на основе состояния?

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 с сокращенной формой (я использую 5.3.1): https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/utils/validation.js

+0

Открыт вопрос об этом на редукционной форме GitHub: https://github.com/erikras/redux-form/issues/1514 –

ответ

2

@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.'; 
    } 
} 

В конце концов, я думаю, что решение, которое полностью исключает валидатор --- и не усложнять логику валидатора и его использование --- было бы гораздо лучше, но сейчас это работает.

С удовольствием принимаем лучший ответ.

EDIT:

Вы также должны убедиться, что в дополнительном поле вынести сценарий, вы также вызвать это значение будет пустой строкой. Прежде чем его коснется, его значение приходит через валидатор как null.

MyForm.JS

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

    if (isGuestOrder && values.email == null) { 
    fields.email.onChange(''); 
    } 
} 
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> размонтирован, проверка будет сброшена для этого поля.