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

In Redux Forms, how do I validate one field based on the value of another?

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

其他例子说我应该可以在props中引用fields数组,但没有这样的数组。 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.

对于 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/

还值得一提的是,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(您可以传递给字段的道具 => 验证)。