React / React Forms / Form Validation
Home /React /React Forms /Form Validation

Form Validation

Form Validation

Validation ensures that data meets your requirements before submission. React gives you flexibility to validate anywhere: on change, on blur, or on submit.

Validation Strategies

Strategy When it fires Best for
On Submit When the form is submitted Simple forms, non-intrusive UX
On Blur When a field loses focus Showing errors after the user finishes typing
On Change Every keystroke Password strength meters, live character counts
Hybrid Blur first, then change after first error Best UX in production forms

Custom Validation:

JSX — ValidatedForm.jsx

import { useState } from 'react';

// Pure validation function — lives outside component for easy testing
function validate(fields) {
  const errors = {};

  if (!fields.email || !fields.email.includes('@')) {
    errors.email = 'Enter a valid email address';
  }
  if (!fields.password || fields.password.length < 8) {
    errors.password = 'Password must be at least 8 characters';
  }
  if (fields.password !== fields.confirm) {
    errors.confirm = 'Passwords do not match';
  }

  return errors; // Empty object = no errors = valid
}

function ValidatedForm() {
  const [fields, setFields]       = useState({ email: '', password: '', confirm: '' });
  const [errors, setErrors]       = useState({});
  const [submitted, setSubmitted] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    const updated = { ...fields, [name]: value };
    setFields(updated);
    if (submitted) setErrors(validate(updated)); // Live re-validate
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setSubmitted(true);
    const errs = validate(fields);
    setErrors(errs);
    if (Object.keys(errs).length === 0) {
      console.log('Valid! Sending to API:', fields);
    }
  };

  const ErrorMsg = ({ field }) =>
    errors[field] ? <span style={{ color: '#a02020', fontSize: '13px' }}>{errors[field]}</span> : null;

  return (
    <form onSubmit={handleSubmit}>
      <input name="email"    value={fields.email}
             onChange={handleChange} type="email" placeholder="Email" />
      <ErrorMsg field="email" />

      <input name="password" value={fields.password}
             onChange={handleChange} type="password" placeholder="Password" />
      <ErrorMsg field="password" />

      <input name="confirm"  value={fields.confirm}
             onChange={handleChange} type="password" placeholder="Confirm password" />
      <ErrorMsg field="confirm" />

      <button type="submit">Sign Up</button>
    </form>
  );
}

export default ValidatedForm;