Menu

Form in React: input, checkbox, select e validazione

Costruisci form in React con input controllati: campi di testo, textarea, select, checkbox e radio button, un solo oggetto di stato per molti campi, invio con onSubmit, messaggi di validazione e le form action di React 19.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Un form React tiene il valore di ogni campo nello stato: l'input mostra value={state} e lo aggiorna con onChange. Quando l'utente invia, un gestore onSubmit chiama e.preventDefault() per fermare il ricaricamento della pagina e poi usa i valori già presenti nello stato.

Scrivi un nome e premi Invio o clicca il pulsante. Poi elimina la riga e.preventDefault();: l'anteprima mostra i campi che il browser avrebbe inviato in un invio nativo, che in una pagina reale la ricaricherebbe anche.

Un input il cui valore arriva dallo stato si chiama input controllato. L'alternativa, lasciare che sia il DOM a tenere il valore e leggerlo più tardi, è trattata in componenti controllati e non controllati.

Input di testo e textarea

Ogni campo di testo funziona allo stesso modo: value dallo stato, onChange legge e.target.value. Una <textarea> segue lo stesso schema. In HTML il suo testo va tra i tag, ma in React lo passi come value.

Poiché imposti tu il valore, puoi cambiare ciò che l'utente ha digitato prima che venga mostrato: il campo del titolo trasforma ogni lettera in maiuscola. Il contatore dei caratteri si aggiorna a ogni tasto perché body è stato e ogni modifica provoca un nuovo render.

Select

Un <select> riceve value sull'elemento select stesso, non selected su un'opzione. e.target.value è il value dell'opzione scelta.

Per una select multipla, aggiungi multiple e passa un array come value. Leggi le scelte con Array.from(e.target.selectedOptions, (o) => o.value).

Checkbox e radio button

Una checkbox si controlla con checked, non con value, e il suo gestore legge e.target.checked, che è true o false. I radio button di un gruppo condividono un name; ognuno è selezionato quando lo stato è uguale al suo valore.

Leggere e.target.value su una checkbox è un errore comune: per una checkbox senza attributo value restituisce la stringa "on" sia che la casella sia spuntata sia che non lo sia.

Un solo oggetto di stato per molti campi

Un form con dieci campi non ha bisogno di dieci chiamate a useState e dieci gestori. Tieni un solo oggetto, dai a ogni input un name che corrisponde a una chiave e scrivi un solo gestore che usa il nome come chiave calcolata: [e.target.name].

Il gestore controlla il tipo di input così la checkbox memorizza un booleano e gli altri memorizzano testo. Per aggiungere un campo aggiungi una chiave all'oggetto iniziale e un input con lo stesso name; il gestore non va modificato. Lo spread mantiene tutti gli altri campi (vedi aggiornare array e oggetti).

Inviare un form

Metti la logica di invio sull'onSubmit del form, non sull'onClick del pulsante. onSubmit scatta anche quando l'utente preme Invio in un campo di testo, cosa che un gestore di clic perderebbe. Un <button> dentro un form è per default un pulsante di invio; dai agli altri pulsanti type="button" così non inviano il form.

Apri la console, scrivi una password e premi Invio: il form registra l'intero oggetto. Cliccare "Clear" non registra nulla, perché è type="button". Togli quell'attributo e anche Clear inizia a inviare il form.

Validazione e messaggi di errore

Una validazione semplice è una funzione che riceve i valori e restituisce un oggetto di messaggi. Eseguila all'invio, salva il risultato nello stato e mostra ogni messaggio sotto il suo campo. Disabilita il pulsante di invio mentre una richiesta è in corso, così un doppio clic non invia il form due volte.

Clicca Save con i campi vuoti per vedere entrambi i messaggi, poi compilali. saveProfile fa le veci di una richiesta reale: attende 800 millisecondi e si risolve. L'attributo noValidate disattiva i fumetti di validazione del browser così compaiono solo i tuoi messaggi; toglilo e aggiungi required a un input per confrontare.

Gli errori possono anche essere calcolati durante il rendering invece che memorizzati, per esempio const emailError = form.email && !form.email.includes('@'), che mostra il messaggio mentre l'utente scrive. Scegli il momento più adatto al form: all'invio è più tranquillo, mentre durante la digitazione dà un riscontro più rapido.

Form action in React 19

React 19 aggiunge un altro modo di gestire un form. Passa una funzione alla prop action del form. React impedisce il ricaricamento della pagina per te e chiama la funzione con un oggetto FormData che contiene ogni campo con un name. I campi non hanno bisogno di stato: sono non controllati, e React li svuota dopo che l'azione termina.

Scrivi un tuo commento e pubblicalo. La lista mostra il tuo testo, e l'input torna a Nice docs: dopo che l'azione si risolve, React riporta i campi non controllati al loro defaultValue. L'azione può essere asincrona, e mentre è in esecuzione React tratta l'aggiornamento come una transizione.

Per mostrare uno stato di attesa o un errore dall'azione, racchiudila con useActionState, che restituisce l'ultimo risultato, un'azione racchiusa per il form e un indicatore isPending. Anche un pulsante in profondità dentro il form può leggere lo stato di attesa con useFormStatus da react-dom:

import { useFormStatus } from 'react-dom';

function SubmitButton() {
    const { pending } = useFormStatus();
    return <button disabled={pending}>{pending ? 'Posting...' : 'Post'}</button>;
}

useFormStatus non è caricato negli editor di questa pagina, quindi compare solo in questo blocco statico. Deve essere chiamato da un componente renderizzato dentro il <form>, non nel componente che renderizza il form.

Lo stato controllato con onSubmit e le form action con FormData funzionano entrambi in React 19. I campi controllati vanno bene per i form che reagiscono mentre scrivi (validazione dal vivo, un contatore di caratteri, campi che dipendono l'uno dall'altro). Le action vanno bene per i form in cui ti servono i valori solo quando l'utente invia.

Domande frequenti

Come si ottiene il valore di un input in React?

Salvalo nello stato e aggiornalo da onChange: <input value={name} onChange={e => setName(e.target.value)} />. Il testo attuale è quindi sempre in name. Per le checkbox leggi e.target.checked invece di e.target.value.

Come si impedisce a un form di ricaricare la pagina in React?

Chiama e.preventDefault() all'inizio del gestore onSubmit. Senza, il browser esegue un normale invio del form, che naviga e ricarica la pagina.

Come si gestiscono molti input con un solo stato in React?

Tieni un solo oggetto nello stato, dai a ogni input un name che corrisponde a una chiave e usa un solo gestore con una chiave calcolata: setForm({ ...form, [e.target.name]: e.target.value }).

Perché in React una textarea usa value invece dei children?

In HTML il testo di una textarea sta tra i suoi tag, ma in React lo passi come value (o defaultValue), allo stesso modo di un input. Così ogni campo di testo in un form React funziona allo stesso modo.

Cosa sono le form action in React 19?

In React 19 puoi passare una funzione a <form action={fn}>. React impedisce il ricaricamento della pagina, chiama la funzione con i FormData del form e azzera i campi non controllati quando termina. useActionState aggiunge sopra un indicatore di attesa e un risultato.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA