React
Form controllati e non: costi reali
Un campo controllato tiene il valore nello stato React, uno non controllato lo lascia al DOM: cambiano i render, la validazione e i file.
In sintesi
- Il campo controllato mette il valore nello stato React, quello non controllato nel DOM.
- Lo stato controllato costa un render per tasto, il campo non controllato zero fino al submit.
- Gli input di tipo file restano non controllati perché il browser non ne imposta il valore.
Un form controllato tiene il valore nello stato React e lo aggiorna a ogni tasto; uno non controllato lascia il valore nel DOM e lo legge al submit.
Chi possiede il valore
Nel form controllato il valore vive in useState: React è l'unica fonte di verità, quindi il campo si può validare e formattare mentre si digita. Nel form non controllato il valore vive nell'elemento HTML: defaultValue imposta il valore iniziale, FormData o un ref lo leggono alla fine. La differenza non è di stile, è chi comanda.
I due schemi, affiancati
function Controlled() {
const [email, setEmail] = useState("");
return setEmail(e.target.value)} />;
}
function Uncontrolled() {
return ;
}
Il primo schema rifà il render del componente a ogni carattere; il secondo lascia fare al browser e costa zero render fino al submit.
Il costo che si paga
- Render per tasto: se lo stato vive nel genitore, un campo controllato in un form da cinquanta campi riaggiorna tutto a ogni lettera.
- Validazione immediata: solo il controllo sullo stato può mostrare un errore mentre si digita, senza leggere il DOM.
- File e campi nativi: un input di tipo file resta non controllato, perché il browser non permette di impostarne il valore.
Un progetto da cui partire
npm create vite@latest form-demo -- --template react
cd form-demo
npm install
npm run dev
Vite, distribuito con licenza MIT, crea il progetto e avvia il server di sviluppo; il campo si modifica in src/App.jsx senza toccare la configurazione.
Record vivi nel catalogo
Tre componenti mostrano i due schemi in uso: credit-card-form, con i campi controllati da una maschera, login-form e otp-input. Per sfogliare per categoria parti da 111.985 componenti.
La limitazione
Nessuno dei due schemi vince sempre. Lo stato controllato in un form grande sposta il costo su React: ogni tasto rirenderizza, e senza stato locale o memo il campo diventa lento. Lo schema non controllato perde la validazione in tempo reale e i campi dipendenti, perché React non vede il valore finché non lo chiedi.
Dove continuare
Il modello generale è in che cos'è React; il confronto fra le librerie di form misurate è in librerie form React; la scelta fra i due framework più diffusi è in Vue 3 vs React.
Domande frequenti
Quale schema conviene per un login?
Il controllato, di solito. Due campi e un pulsante costano pochi render, e la validazione immediata vale più del risparmio.
Posso mescolare controllati e non controllati?
Sì, e spesso è la scelta giusta. Il campo di ricerca e i file restano non controllati, il resto va nello stato o in una libreria di form.
Perché un input file non si può controllare?
Perché il browser non consente di impostare il valore di un input di tipo file per sicurezza. Si legge da FormData o da un ref.
Un controlled input lento è un problema del browser?
No, del componente. Lo stato troppo in alto rirenderizza l'intero form: sposta lo stato nel campo o usa react-hook-form.
react-hook-form è obbligatorio per i form grandi?
No, ma evita il costo per tasto con campi non controllati e sottoscrizioni per campo. È distribuito con licenza MIT.