Skip to Content
Nextjs1.5 Forms & Controlled Inputs

Forms & Controlled Inputs 📝

Controlled inputs are like smart whiteboards: React keeps an authoritative copy of the text, ensuring UI and state never drift apart.

Controlled Basics ✍️

'use client'; import { useState } from 'react'; export function NewsletterForm() { const [email, setEmail] = useState(''); const handleSubmit = (evt: React.FormEvent) => { evt.preventDefault(); subscribe(email); }; return ( <form onSubmit={handleSubmit}> <label> Email <input value={email} onChange={e => setEmail(e.target.value)} /> </label> <button disabled={!email.includes('@')}>Join</button> </form> ); }
  • The value prop reflects state; onChange updates state.
  • Keeps validation, formatting, and UI feedback centralized.

Multiple Fields 🌱

const [form, setForm] = useState({ name: '', role: 'dev' }); const handleChange = (evt: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const { name, value } = evt.target; setForm(prev => ({ ...prev, [name]: value })); };
  • Use name attributes to update arbitrary fields.
  • Consider useReducer for complex forms.

Server Actions & Forms ⚙️

  • In Next.js App Router, forms can call server actions via action={async formData => ...}.
  • Validate both client-side (UX) and server-side (security).

Controlled vs Uncontrolled ⚖️

  • Controlled: React state is the source of truth (most predictable).
  • Uncontrolled: rely on DOM state + refs (defaultValue, ref.current.value). Useful for simple forms or performance-sensitive inputs.

UX Tips 💡

  • Debounce expensive operations triggered on onChange (e.g., search suggestions).
  • Use useRef to manage focus/selection after submit.
  • Provide inline validation messages synchronized with state.

Analogy: controlled inputs are shared Google Docs—everyone edits the same canonical version, so there are no conflicting copies.

Mastering them makes integrating Next.js server features (actions, mutations) smooth and predictable. ✅

Last updated on