- Redux Form
- Examples
- Async Validation Example
Async Blur Validation Example
The recommended way to provide server-side validation is to use Submit Validation, but there may be instances when you want to run server-side validation while the form is being filled out. The classic example of this letting someone choose a value, like a username, that must be unique within your system.
To provide asynchronous validation, provide redux-form
with an asynchronous validation function (asyncValidate
) that takes an object of form values, and the Redux dispatch
function, and returns a promise that either rejects with an object of errors or resolves.
You will also need to specify which fields should fire the asynchronous validation when they are blurred with the asyncBlurFields
config property.
Important
- Asynchronous validation will be called before the
onSubmit
is fired, but if all you care about is validationonSubmit
, you should use Submit Validation. - Asynchronous validation will not be called if synchronous validation is failing for the field just blurred.
The errors are displayed in the exact same way as validation errors created by Synchronous Validation.
How to use the form below:
- Usernames that will fail validation:
john
,paul
,george
orringo
.
Form
Values
undefined
Code
validate.js
const validate = values => {
const errors = {}
if (!values.username) {
errors.username = 'Required'
}
if (!values.password) {
errors.password = 'Required'
}
return errors
}
export default validate
asyncValidate.js
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
const asyncValidate = (values/*, dispatch */) => {
return sleep(1000) // simulate server latency
.then(() => {
if ([ 'john', 'paul', 'george', 'ringo' ].includes(values.username)) {
throw { username: 'That username is taken' }
}
})
}
export default asyncValidate
AsyncValidationForm.js
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import validate from './validate'
import asyncValidate from './asyncValidate'
const renderField = ({ input, label, type, meta: { asyncValidating, touched, error } }) => (
<div>
<label>{label}</label>
<div className={asyncValidating ? 'async-validating' : ''}>
<input {...input} type={type} placeholder={label}/>
{touched && error && <span>{error}</span>}
</div>
</div>
)
const AsyncValidationForm = (props) => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Field name="username" type="text" component={renderField} label="Username"/>
<Field name="password" type="password" component={renderField} label="Password"/>
<div>
<button type="submit" disabled={submitting}>Sign Up</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
</div>
</form>
)
}
export default reduxForm({
form: 'asyncValidation', // a unique identifier for this form
validate,
asyncValidate,
asyncBlurFields: [ 'username' ]
})(AsyncValidationForm)