Real World Example

Real World: Job application form

Real forms validate each field, show errors under the field, disable the button while submitting, and send the data to an API.

function ApplyForm({ jobId }) {
  const [form, setForm] = useState({ name: '', email: '', phone: '', experience: '0-1' });
  const [errors, setErrors] = useState({});
  const [submitting, setSubmitting] = useState(false);

  const validate = () => {
    const e = {};
    if (!form.name.trim()) e.name = 'Name is required';
    if (!/^\S+@\S+\.\S+$/.test(form.email)) e.email = 'Invalid email';
    if (!/^\d{10}$/.test(form.phone)) e.phone = 'Enter a 10-digit phone number';
    return e;
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const found = validate();
    setErrors(found);
    if (Object.keys(found).length) return;
    setSubmitting(true);
    await fetch('/api/jobs/' + jobId + '/apply', { method: 'POST', body: JSON.stringify(form) });
    setSubmitting(false);
  };

  return <form onSubmit={handleSubmit}>{/* inputs + {errors.email && <p>{errors.email}</p>} */}<button disabled={submitting}>Apply</button></form>;
}