Inline form validations — UX design considerations and React examples

Validating forms well can be a tricky proposition. In this article, we’ll review some of the UX design considerations you need to think about with inline validations. I review asynchronous inline form validation considerations, discuss the “reward early, validate late” inline validation pattern, and finally demonstrate an example of this pattern using my React hooks-based forms API.

In Mihael Konjević’s article Inline validation in forms — designing the experience, Mihael exhaustively researches several inline validation patterns and recommends the inline validation pattern “reward early, punish late”. To put a more positive spin on the term in this article, I’ll go with “reward early, validate late”.

What are inline validations?

Inline validations validate input fields immediately and provide validation feedback inline, typically next to the input field. During form submit, a form will almost always evaluate all validations including the inline ones before continuing with form submission.

Inline validations provide feedback early and often to end users, so they provide a significant usability benefit. Inline validations will normally be triggered either when an input field changes (the onChange event), or when a user focuses out of an input field (the onBlur event).

What is the “reward early, validate late” inline validation pattern?

The “reward early, validate late” validation pattern applies a validator to an input field both onChange and onBlur. However, full validation does not always happen onChange. It sounds inconsistent on paper, but it actually provides a more user-friendly experience.

Figure 1 below is an animated visual depicting some “reward early, validate late” examples.

Validate late

You can see that when the user first types in the empty “Username” field, then clears the “Username” field value, visually the input field appears fine. It is only when the user blurs away from the input field that the “Username” required field validation kicks in. This is the “ validate late” part of the validation pattern.

Reward early

Reward early only applies when an inline validation is being presented to an end user. So if the “Username” field is displaying the required validation error, whenever the user changes the value of “Username”, validation immediately fires “onChange”. This allows the UI to reward the user earlier.

Figure 1 — hybrid inline validation approach — reward early, validate late

Reward early, validate late validation flow

The “reward early, validate late” pattern can be generalized into the following flows. “Pristine” means that the input’s current value is the same as the input’s original starting value. “Dirty” means that the input’s current value differs from the input’s original starting value.

Initial input state = valid sequence

  • Input receives focus
  • User changes input value, triggering an onChange event. No input validations are evaluated
  • Input changes to state = dirty
  • User blurs away from input
  • Input validations run and validation state is set
  • Input validation state becomes either valid or invalid

Initial input state = invalid sequence

  • Input receives focus
  • User changes input value, triggering an onChange event
  • Input validations are evaluated and the validation state is set
  • Input validation state becomes either valid or invalid

In a nutshell, “reward early, validate late” uses the onChange and onBlur input events, but onChange only triggers input validation when the input state upon focus is invalid.

Asynchronous inline validations

“Reward early, validate late” is a very user-friendly validation pattern, but I recommend avoiding it where inline validations need to run asynchronously, such as when they have to perform remote HTTP requests.

Asynchronous inline validations are not able to effectively “reward early” due to the delay factor required by asynchronous operations to complete. In addition, asynchronous validations that hit remote endpoints incur additional network traffic and can impact the mobile user experience, so their invocation should be carefully considered.

If an asynchronous inline validation is needed and it hits a remote endpoint, I recommend triggering the inline validation either onBlur, or if onChange, providing you’re debouncing the event, in order to reduce network traffic.

What is debounce

To get familiarized with debounce, feel free to review Debounce in JavaScript — Improve Your Application’s Performance by Trey Huffine, or if you are more visually inclined, check out David Corbacho’s article Debouncing and Throttling Explained Through Examples.

Asynchronous versus synchronous inline validations

As much as asynchronous inline validations might seem to be useful, the use cases are probably somewhat limited to cases where an input needs to be looked up in a database. For example, an inline validation that checks if a user name field is globally unique.

Otherwise, if the benefit is questionable, carefully consider if an asynchronous validation is really needed. Consider migrating them to synchronous options if they are nonessential.

Code examples

In the following code example, I use my react-hooks-form-util library to create a form with an asynchronous inline validation, and with an input that demonstrates the “reward early, validate late” pattern. The “First name” field uses the pattern. Compare the field to the other fields. You’ll see that the validation errors are shown and hidden at more optimal times.

Reward early, validate late input pattern

Inline validations can be tricky. Deciding when to run inline validations is not straightforward. The “reward early, validate late” inline validation pattern can reduce user frustration because it provides the user with immediate, positive feedback when a form field has been corrected. It’s a useful inline validation pattern that I recommend you evaluate and possibly give a spin with your next form!