在Redux Forms中,如何根据另一个字段的值验证一个字段?

时间:2017-01-18 08:57:15

标签: validation reactjs redux-form

我正在使用Redux Form版本6.4.3,我正在尝试验证两个日期字段,以便'到'日期必须始终在'from'日期之前。

其他示例说我应该能够引用fields中的props数组,但是没有这样的数组。 form state有一个名为registeredFields的数组,但这些数组似乎只是{name: 'dob', type: 'Field'}

的形式

这是我的表单代码

import React      from 'react'
import DatePicker from 'react-bootstrap-date-picker'
import moment     from 'moment'

import {Field, reduxForm} from 'redux-form'
import {Form, Row, Col, Button, FormGroup, ControlLabel, FormControl, HelpBlock} from 'react-bootstrap'

// validations
const required = value => !value ? 'This field is required' : undefined
const maxDate = max => value =>
  value && moment(value).isAfter(max) ? `Must be before ${max}` : undefined
const minDate = min => value =>
  value && moment(value).isBefore(min) ? `Must be after ${min}` : undefined

const renderDatepicker = ({ input, label, hint, showTodayButton, meta: { pristine, touched, warning, error } }) => {
  const validationState = pristine ? null : error ? 'error' : warning ? 'warning' : null
  return (
  <FormGroup validationState={validationState}>
    <Col componentClass={ControlLabel} sm={3}>{label}</Col>
    <Col sm={3}>
      <FormControl
        {...input}
        componentClass={DatePicker}
        placeholder="DD/MM/YYYY"
        dateFormat="DD/MM/YYYY"
        showTodayButton={showTodayButton}/>
    </Col>
    {pristine && !!hint && (
      <Col sm={6}>
        <HelpBlock>{hint}</HelpBlock>
      </Col>
    )}
    {touched && (
      (error && (
        <Col sm={6}>
          <HelpBlock>{error}</HelpBlock>
        </Col>)
      ) || (warning && (
        <Col sm={6}>
          <HelpBlock>{warning}</HelpBlock>
        </Col>
      ))
    )}
  </FormGroup>
)}

const MyForm = props => {
  const { error, handleSubmit, pristine, reset, submitting, fields } = props
  console.debug('fields', fields) // fields is undefined
  return (
    <Form horizontal>
      <Field
        name="dateFrom"
        component={renderDatepicker}
        label="Date from"
        hint="Earliest date for enquiry"
        validate={[required, maxDate('where do I get the other date value from?')]}
      />
      <Field
        name="dateTo"
        component={renderDatepicker}
        label="Date to"
        showTodayButton={true}
        hint="Latest date for enquiry"
        validate={[required, minDate('where do I get the other date value from?')]}
      />
    </Form>
  )
}

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

我感觉我错过了一些明显的东西,因为我看到的所有例子都希望fields中存在props数组。

2 个答案:

答案 0 :(得分:9)

还值得一提的是Field的验证函数签名是validate : (value, allValues, props) => error [optional],因此您实际上也可以在字段级验证中引用其他字段值。

我相信你可以这样做:

const maxDateValidationAdapter = (value, values) => maxDate(values.dateTo)(value);
// Alternatively, if maxDate() is used only in this form you can just change its signature
<Field
    name="dateFrom"
    component={renderDatepicker}
    label="Date from"
    hint="Earliest date for enquiry"
    validate={[required, maxDateValidationAdapter]}
/>

请参阅Field documentation(道具您可以传递给Field =&gt;验证)。

答案 1 :(得分:2)

对于Redux表格,请使用:

export default reduxForm({
  form: 'MyForm',  // a unique identifier for this form
  validate,                // <--- validation function given to redux-form
})(MyForm)

const validate = values => {
  const errors = {}
  // Here you can get all the fields in value object, use value.min or value.max
  return errors
}

http://redux-form.com/6.4.3/examples/syncValidation/