Docs LogoDocs

Forms & Validation - Handling User Input

Documentation for Forms & Validation - Handling User Input.

Forms & Validation - Handling User Input

What are Forms in React?

React forms manage user input through controlled components and state.

Controlled vs Uncontrolled

FeatureControlledUncontrolled
Value sourceReact stateDOM
Get valueState variableref.current.value
Best forMost formsFile inputs, simple

Controlled Components

function TextInput() {
  const [name, setName] = useState("");

  return (
    <input type="text" value={name} onChange={(e) => setName(e.target.value)} />
  );
}

Handling Multiple Inputs

function Form() {
  const [form, setForm] = useState({ name: "", email: "" });

  const handleChange = (e) => {
    const { name, value, type, checked } = e.target;
    setForm((prev) => ({
      ...prev,
      [name]: type === "checkbox" ? checked : value,
    }));
  };

  return (
    <form>
      <input name="name" value={form.name} onChange={handleChange} />
      <input name="email" value={form.email} onChange={handleChange} />
    </form>
  );
}

Form Submission

function ContactForm() {
  const [form, setForm] = useState({ name: '', message: '' });
  const [status, setStatus] = useState('idle');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setStatus('submitting');

    try {
      await fetch('/api/contact', {
        method: 'POST',
        body: JSON.stringify(form)
      });
      setStatus('success');
    } catch {
      setStatus('error');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="name" value={form.name} onChange={...} />
      <button disabled={status === 'submitting'}>Send</button>
      {status === 'success' && <p>Sent!</p>}
    </form>
  );
}

Basic Validation

function ValidatedForm() {
  const [email, setEmail] = useState("");
  const [errors, setErrors] = useState({});

  const validate = () => {
    const newErrors = {};
    if (!email) newErrors.email = "Required";
    else if (!/\S+@\S+\.\S+/.test(email)) newErrors.email = "Invalid";
    return newErrors;
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const newErrors = validate();
    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }
    // Submit
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      {errors.email && <span>{errors.email}</span>}
      <button>Submit</button>
    </form>
  );
}

Real-time Validation

function RealTimeValidation() {
  const [email, setEmail] = useState("");
  const [touched, setTouched] = useState(false);

  const isValid = /\S+@\S+\.\S+/.test(email);
  const showError = touched && !isValid;

  return (
    <div>
      <input
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        onBlur={() => setTouched(true)}
      />
      {showError && <span>Invalid email</span>}
    </div>
  );
}

Interview Questions & Answers

Q1: What is the difference between controlled and uncontrolled components?

Controlled: React state controls value via value + onChange. Uncontrolled: DOM manages value, access via ref. Controlled is preferred for real-time validation, conditional logic. Uncontrolled for file inputs or simplicity.


Q2: Why use e.preventDefault() in form handlers?

Stops browser's default form submission (page reload), allowing React to handle submission via JavaScript for SPA behavior, async operations, and validation.


Q3: How do you handle multiple inputs with one handler?

Use name attribute matching state keys: setForm(prev => ({ ...prev, [e.target.name]: e.target.value })). Check e.target.type for checkboxes.


Q4: How do you implement form validation?

On submit: validate all fields, set errors state. Real-time: validate on change/blur. Use libraries (React Hook Form, Formik) for complex forms. Track touched to show errors after interaction.


Q5: What's the difference between value and defaultValue?

value = controlled (React manages). defaultValue = uncontrolled (initial value, DOM manages). Don't mix them.


Q6: How do you handle file inputs?

File inputs are uncontrolled. Access via e.target.files[0] in onChange. Reset with ref: inputRef.current.value = ''.


Q7: When should you use form libraries?

Use Formik/React Hook Form for: many fields, complex validation, dynamic fields, or to reduce boilerplate. Simple forms don't need them.


Q8: How do you implement dynamic form fields?

Store as array: [{ id, value }]. Map to render, add with [...fields, newField], remove with filter, update with map. Use stable ids as keys.


Q9: How do you create a multi-step form?

Track step in state, render different fields per step, persist all data in single state object, validate per step, submit on final step.


Q10: How do you handle server errors?

Catch API errors, map to form field errors, update errors state, display alongside client errors, clear on field change.

Last updated on July 15, 2026

On this page