New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to perform async validation? #25
Comments
I was able to figure out a good solution with the current API. I just created a form field called import { Form, Text, FormField } from 'react-form';
let lastQuery = {email: ''};
function CustomInput ({field, query, method, ...rest}) {
return (
<FormField field={field}>
{({ setValue, getValue, setTouched }) => {
if (query.email !== lastQuery.email) {
lastQuery = query;
setTimeout(() => {
if (query.email === 'marshall@creativeideal.net') {
setValue('That email is unavailable');
} else {
setValue('');
}
}, 500);
}
return (
<input
type='hidden'
value={getValue()}
/>
);
}}
</FormField>
);
}
ReactDOM.render(
<div>
<div className='container react-form'>
<h2>Login - React-Form</h2>
<Form
onSubmit={(values) => {
console.log('Success!', values);
}}
defaultValues={{
email: '',
password: '',
emailError: ''
}}
validate={({ email, password, emailError }) => {
let validations = {
email: !email ? 'E-mail address is required' : emailError || null,
password: !password ? 'Password is required' : null
};
return validations;
}}
>
{(props) => {
let {values, submitForm} = props;
let query = {
email: values.email
};
return (
<form onSubmit={submitForm} className='auth-component-form'>
<Text field='email' placeholder='e-mail address' />
<Text field='password' type='password' placeholder='password' />
<CustomInput field='emailError' query={query} />
<button type='submit'>Submit</button>
</form>
);
}}
</Form>
</div>
</div>
); |
Interesting approach. Would it be valuable if react-form supported async lifecycle methods? This would be a lot of work, but it could be extremely useful for circumstances like this one. Imagine returning a promise in the |
Built in async support would be nice, possibly. I was studying form.js looking at where it would be useful. Maybe if we could make it possible to specify a Promise (or a function that returns one) for individual validation attributes. The class-level validate method and its recursive utils could keep track of promises and re-run or perform cleanup after a resolve or reject. This would make it so that non-promise validation attributes could continue to update synchronously if an async request runs long. The only thing it wouldn't address that the above example does address is the ability to mix sync and async validations together. It's really nice to get the immediate feedback of the sync validations; keeps the form responsive to user interaction. I'm not sure the amount of effort would be worth the benefits, though. It's definitely something to think about. Thanks again! |
Interesting idea indeed. I'm intrigued by the idea of returning a promise for a validation message instead of the whole object. That would allow exactly what you're imagining: mixed validation timing. It might be simple enough to maintain a promise queue that maps to validation fields as they come in. As those promises resolve, update the view, and also replace them with new ones if the field is changed again. Thinking of it that way, it doesn't seem like it would be too much work. Are there any other locations in the api that promises would be beneficial? |
Would that affect performance in large forms? |
I doubt it would feel much different using promises, but it more than likely wouldn't be a breaking change. It can be written so that using the current API doesn't run any of the code for Promises.
@tannerlinsley I'll see if I have more feedback after I try to implement the example I posted. |
You have created an amazing form library. Thank you.
I want to integrate this into my auth-component project. I need to be able to run a validation to check if the username is available as the user is typing in the text field. Is this possible with the current API? If not, I can try to help add the feature, if you are open to it.
The text was updated successfully, but these errors were encountered: