Email validation is one of those things conventional frontend wisdom says to steer clear of, because:
- the endless complexity in how email works and
- because even if an email looks valid, it might not exist on the remote server.
This is backend territory.
However.
We can hijack the browser’s built-in email validation in <input type="email">
fields to give the user a better experience.
CSS validation
At the simplest, <input type="email">
fields expose :valid
and :invalid
pseudo selectors.
We can change the style of our inputs when the email is invalid:
input:invalid{
border-color: red;
}
Nice. Zero lines of Javascript. This is by far the best way to do form validation in the year ${year}.
Plain Javascript email validation
The constraints validation API exposes all of this same built-in browser validation to Javascript.
To check if your email is valid in plain JS:
const emailField = document.querySelector('.myEmailInput');
const isValid = emailField.validity ? !emailField.validity.typeMismatch : true;
This works in all the latest browsers and falls back to true
in those that don’t support the API.
React email validation hook
Lol just kidding, you don’t need a hook. Check this out:
const [emailIsValid, setEmailIsValid] = useState(false);
return <input
type="email"
onChange={e => setEmailIsValid(e.target.validity ? !e.target.validity.typeMismatch : true)}
/>
We can use the same native JS dom API to check the validity of the field as the user types.
This is by far the fastest way to validate email in react, requires almost no code, and kicks all the responsibility back to the browser to deal with the hard problems.
More form validation
Email validation is hard, and all browsers have slightly different validation functions.
But for all the complexity of email validation, it’s best to trust the browser vendor implementation because it’s the one that’s been tested on the 4+ billion internet users out there.
For further reading, MDN has great docs for validating forms in native CSS and Javascript code.
You should also inspect the e.target.validity
object for clues to what else you can validate using native browser functions.
It’s a brave new world, friends.