Blog>
Snippets

Handling Validation States with UI Feedback

Illustrate handling different validation states (loading, success, error) in TanStack Form and providing corresponding UI feedback to the user.
import { useForm, useField } from '@tanstack/react-form';

// Custom validation hook
function useAsyncValidation(value, validateFunction) {
  const [state, setState] = useState({ loading: false, error: null, success: false });

  useEffect(() => {
    setState({ loading: true, error: null, success: false });
    validateFunction(value)
      .then(() => setState({ loading: false, error: null, success: true }))
      .catch(error => setState({ loading: false, error, success: false }));
  }, [value]);

  return state;
}
This piece defines a custom hook, `useAsyncValidation`, which manages the validation state (loading, error, success) based on the asynchronous validation result of a given value.
function AsyncValidationTextInput({ fieldKey, validate }) {
  const { getInputProps, meta } = useField(fieldKey);
  const { value } = meta;
  const validationState = useAsyncValidation(value, validate);

  return (
    <div>
      <input type='text' {...getInputProps()} />
      {validationState.loading && <span>Loading...</span>}
      {validationState.error && <span style={{ color: 'red' }}>{validationState.error.message}</span>}
      {validationState.success && <span style={{ color: 'green' }}>Success!</span>}
    </div>
  );
}
This component, `AsyncValidationTextInput`, uses the `useAsyncValidation` hook along with TanStack's `useField` to provide UI feedback based on the current validation state of an input field.
function MyForm() {
  const myForm = useForm({ 
    onSubmit: async values => { /* handle submission */ }, 
    validate: async values => { /* define synchronous or asynchronous form-level validation */ } 
  }); 

  return (
    <form onSubmit={myForm.handleSubmit}>
      <h1>My Async Validation Form</h1>
      <AsyncValidationTextInput fieldKey='myInputField' validate={async (value) => { /* custom async validation logic here */ }} />
      <button type='submit'>Submit</button>
    </form>
  );
}
This form component setup employs TanStack's `useForm` hook and integrates the `AsyncValidationTextInput` component for managing the field with asynchronous validation, offering immediate UI feedback to the user.