You can use controlled components with useState, uncontrolled components with refs, or form libraries like React Hook Form for complex needs.
Form handling in React typically follows one of three approaches, each suited to different situations.
Controlled components tie input values to React state. Every keystroke triggers onChange, updating state, which updates the input value. This gives you full control: validate on every change, format input, or conditionally enable/disable submit. The downside is more code and potentially more re-renders.
Uncontrolled components use refs to access DOM values directly. You read values when needed (like on submit) rather than tracking every change. Less code, fewer re-renders, but less control over the input during typing. Good for simple forms where you just need final values.
Form libraries like React Hook Form, Formik, or TanStack Form handle complex scenarios elegantly. They provide validation (often with Zod or Yup schemas), error handling, touched/dirty state, array fields, and more. React Hook Form is especially popular for its minimal re-renders and hook-based API.
For simple forms with a few fields, controlled components are fine. For complex forms with validation, dynamic fields, or many inputs, a form library saves significant time and provides better UX patterns out of the box.
You can use controlled components with useState, uncontrolled components with refs, or form libraries like React Hook Form for complex needs.
Join our network of elite AI-native engineers.