React Redux Form failing required validation even when set with initialValues

Viewed 873

I have a React Redux Form which has a few required fields and has its initial values set with initialValues prop

The values initialize fine, but when I try to save the form it errors saying the field is required (even though there's a value in there). If I simply CLICK into the field then save again everything works fine!

I have tried every way I can find using initialize/reset/destroy/change/blur/etc to manually touch or set the field all to no avail

reduxForm({
    form: 'formName',
    touchOnChange: true,
    touchOnBlur: true
}),

useEffect(() => {
    if (initialValues && initialValues.field) {
        change(field, value)
        blur(field, value)
    }
}, [initialValues])

and a whole slew of different options as above

Same behavior if I try to reset and re-init the form, or call change. If I just click into the field though then the validation passes as expected.

Also tried enableReinitialize: true but that didn't change the behavior either

initialValues is set via an async call which updates redux state var, I'm guessing this is the issue at hand. I've been unable to reproduce with any of the mvp sandbox examples.

The values are getting set just fine in the fields but it's like the validators just aren't checking the field after the initialValue is set unless the user performs a mouse click in them.

How can I tell the form there's already a value in there just check, without the user manually clicking into the field

-- some new info

If I manually touch and then blur the field ... the validation fails immediately instead of waiting for submit to be pressed, so it really must think there's no value in the input until there's a mouse click there

1 Answers

It looks like you are in need of a form validation. The below is a example form / form validation from https://redux-form.com/6.0.1/examples/submitvalidation/.

submit.js

import { SubmissionError } from 'redux-form'

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

function submit(values) {
  return sleep(1000) // simulate server latency
    .then(() => {
      if (![ 'john', 'paul', 'george', 'ringo' ].includes(values.username)) {
        throw new SubmissionError({ username: 'User does not exist', _error: 'Login failed!' })
      } else if (values.password !== 'redux-form') {
        throw new SubmissionError({ password: 'Wrong password', _error: 'Login failed!' })
      } else {
        window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
      }
    })
}

export default submit

SubmitValidationForm.js

import React from 'react'
import { Field, reduxForm } from 'redux-form'
import submit from './submit'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type}/>
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const SubmitValidationForm = (props) => {
  const { error, handleSubmit, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit(submit)}>
      <Field name="username" type="text" component={renderField} label="Username"/>
      <Field name="password" type="password" component={renderField} label="Password"/>
      {error && <strong>{error}</strong>}
      <div>
        <button type="submit" disabled={submitting}>Log In</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'submitValidation'  // a unique identifier for this form
})(SubmitValidationForm)

Good luck!

Related