How do I perform input validations in React?

I hear this question quite often: How do I perform input validations in React? I have two answers. One answer is simple: Use redux-form. The other answer is what I do: Use plain JavaScript. This article is about how I do input validations using plain JavaScript.

Consider a simple form with a name input, email input and submit button. Let us validate name and email.

render() {
  const { name, email } = this.state;
  return (
    <form onSubmit={this.handleSubmit}>
      <input
        type="text"
        placeholder="Enter name"
        value={name}
        onChange={e => {
          this.setState({ name: e.target.value });
        }}
        />
      <input
        type="email"
        placeholder="Enter email"
        value={email}
        onChange={e => {
          this.setState({ email: e.target.value });
        }}
        />
      <button type="submit">Submit</button>
    </form>
  );
}

Validations

The form has controlled input elements. Name is a required field. Email should follow a regex pattern. To validate the name and email fields, I use plain JavaScript functions like so.

validateName() {
  const { name } = this.state;
  const nameError = name ? '' : 'Name is required';
  this.setState({ nameError });
  return !nameError;
}

validateEmail() {
  const { email } = this.state;
  const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  const emailError = regex.test(email) ? '' : 'Email is not valid';
  this.setState({ emailError });
  return !emailError;
}

Event handlers

There are two places we have to validate the input elements. One place is when we submit the form. The other place is when the value of the input changes.

handleSubmit = e => {
  e.preventDefault();
  const validName = this.validateName();
  const validEmail = this.validateEmail();
  if (validName && validEmail) {
    // submit the form
  }
};

handleNameChange = e => {
  this.setState({ name: e.target.value }, () => {
    this.validateName();
  });
};

handleEmailChange = e => {
  this.setState({ email: e.target.value }, () => {
    this.validateEmail();
  });
};

I wait for the state changes to complete before performing validations.

Finally, we add a little bit of HTML to show the error.

<div>
  <input
    type="email"
    placeholder="Enter email"
    value={email}
    onChange={this.handleEmailChange}
    className={emailError && "error-control"}
  />
</div>
<div className="error-text">{emailError}</div>

And some CSS tweaks to make it appear like an error.

.error-text {
  color: red;
}

.error-control {
  border: 1px solid red;
}

The good thing about using plain JavaScript for validations is that we have more control over how we show the error message.

Don’t worry if you did not follow all along. The whole code is available in CodePen. And it works!

UPDATE: A better way to handle input validation is outlined in the article: UX Design for Input Validation in React.

Related Posts

Leave a Reply

Your email address will not be published.