AtomLearnAtomLearn
DashboardGoalsPathAchievementsReviewSign In
DashboardReactForms in React
ReactNot Started

Forms in React

Controlled inputs, form state, validation, and submission

0%
Knowledge0%
Learn & Drill
Fluency0%
Drill & Speed
Retention0%
Mastery & Review
Confidence0%
All modes
Practice

Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.

Upgrade
Knowledge
Fluency
Retention

Knowledge Debt detected

You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.

Explanation

React forms use s — the form field value is driven by React state.

jsx
function SignupForm() {
  const [form, setForm] = useState({ email: '', password: '' });
  const [error, setError] = useState('');

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

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!form.email.includes('@')) {
      setError('Invalid email');
      return;
    }
    // submit logic
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" value={form.email} onChange={handleChange} />
      <input name="password" type="password" value={form.password} onChange={handleChange} />
      {error && <p className="error">{error}</p>}
      <button type="submit">Sign Up</button>
    </form>
  );
}

Why controlled inputs:

  • React is the single source of truth
  • You can validate on every keystroke
  • Easy to programmatically clear or prefill

Checkbox and select:

jsx // Checkbox <input type="checkbox" checked={agree} onChange={e => setAgree(e.target.checked)} /> // Select <select value={role} onChange={e => setRole(e.target.value)}> <option value="user">User</option> <option value="admin">Admin</option> </select>

Uncontrolled inputs with ref exist but are less common in React.

Examples

Generic handleChange for any field

One generic handler for all inputs using computed property names

const [form, setForm] = useState({ name: '', email: '', role: 'user' });

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

// All inputs use the same handler — just set name= correctly
<input name="name"  value={form.name}  onChange={handleChange} />
<input name="email" value={form.email} onChange={handleChange} />

Real-time validation

Validate on every keystroke using derived state

function EmailInput() {
  const [email, setEmail] = useState('');
  const isValid = email === '' || email.includes('@');

  return (
    <div>
      <input
        type="email"
        value={email}
        onChange={e => setEmail(e.target.value)}
        className={isValid ? '' : 'input-error'}
      />
      {!isValid && <span className="error-text">Enter a valid email</span>}
    </div>
  );
}

How well did you understand this?

Next in React

Lifting State Up

Continue