Il componente browser integrato <input> ti permette di renderizzare diversi tipi di input per i form.
<input />Reference
<input>
Per visualizzare un input, renderizza il componente browser integrato <input>.
<input name="myInput" />Props
<input> supporta tutte le props comuni degli elementi.
formAction: Una stringa o una funzione. Sostituisce l’<form action>padre pertype="submit"etype="image". Quando aactionviene passato un URL, il form si comporterà come un form HTML standard. Quando aformActionviene passata una funzione, la funzione gestirà l’invio del form. Vedi<form action>.
Puoi controllare un input passando una di queste props:
checked: Un booleano. Per un input checkbox o un radio button, controlla se è selezionato.value: Una stringa. Per un input di testo, controlla il suo testo. (Per un radio button, specifica i suoi dati del form.)
Quando passi una delle due, devi anche passare un gestore di eventi onChange che aggiorni il valore passato.
Queste props di <input> sono rilevanti solo per input non controllati:
defaultChecked: Un booleano. Specifica il valore iniziale per inputtype="checkbox"etype="radio".defaultValue: Una stringa. Specifica il valore iniziale per un input di testo.
Queste props di <input> sono rilevanti sia per input non controllati che controllati:
accept: Una stringa. Specifica quali tipi di file sono accettati da un inputtype="file".alt: Una stringa. Specifica il testo alternativo dell’immagine per un inputtype="image".capture: Una stringa. Specifica il media (microfono, video o fotocamera) catturato da un inputtype="file".autoComplete: Una stringa. Specifica uno dei possibili comportamenti di autocomplete.autoFocus: Un booleano. Setrue, React metterà a fuoco l’elemento al montaggio.dirname: Una stringa. Specifica il nome del campo del form per la direzionalità dell’elemento.disabled: Un booleano. Setrue, l’input non sarà interattivo e apparirà attenuato.children:<input>non accetta children.form: Una stringa. Specifica l’iddel<form>a cui appartiene questo input. Se omesso, è il form padre più vicino.formAction: Una stringa. Sostituisce l’<form action>padre pertype="submit"etype="image".formEnctype: Una stringa. Sostituisce l’<form enctype>padre pertype="submit"etype="image".formMethod: Una stringa. Sostituisce il<form method>padre pertype="submit"etype="image".formNoValidate: Una stringa. Sostituisce il<form noValidate>padre pertype="submit"etype="image".formTarget: Una stringa. Sostituisce il<form target>padre pertype="submit"etype="image".height: Una stringa. Specifica l’altezza dell’immagine pertype="image".list: Una stringa. Specifica l’iddel<datalist>con le opzioni di autocomplete.max: Un numero. Specifica il valore massimo degli input numerici e datetime.maxLength: Un numero. Specifica la lunghezza massima di testo e altri input.min: Un numero. Specifica il valore minimo degli input numerici e datetime.minLength: Un numero. Specifica la lunghezza minima di testo e altri input.multiple: Un booleano. Specifica se sono consentiti valori multipli per<type="file"etype="email".name: Una stringa. Specifica il nome di questo input che viene inviato con il form.onChange: Una funzione gestore diEvent. Obbligatorio per input controllati. Scatta immediatamente quando il valore dell’input viene modificato dall’utente (ad esempio, scatta a ogni battitura). Si comporta come l’eventoinputdel browser.onChangeCapture: Una versione dionChangeche scatta nella fase di capture.onInput: Una funzione gestore diEvent. Scatta immediatamente quando il valore viene modificato dall’utente. Per ragioni storiche, in React è idiomatico usareonChangeal suo posto, che funziona in modo simile.onInputCapture: Una versione dionInputche scatta nella fase di capture.onInvalid: Una funzione gestore diEvent. Scatta se un input non supera la validazione all’invio del form. A differenza dell’eventoinvalidintegrato, l’evento ReactonInvalidfa bubbling.onInvalidCapture: Una versione dionInvalidche scatta nella fase di capture.onSelect: Una funzione gestore diEvent. Scatta dopo che la selezione all’interno dell’<input>cambia. React estende l’eventoonSelectper scattare anche con selezione vuota e durante le modifiche (che possono influenzare la selezione).onSelectCapture: Una versione dionSelectche scatta nella fase di capture.pattern: Una stringa. Specifica il pattern che ilvaluedeve rispettare.placeholder: Una stringa. Visualizzata con un colore attenuato quando il valore dell’input è vuoto.readOnly: Un booleano. Setrue, l’input non è modificabile dall’utente.required: Un booleano. Setrue, il valore deve essere fornito affinché il form possa essere inviato.size: Un numero. Simile all’impostazione della larghezza, ma l’unità dipende dal controllo.src: Una stringa. Specifica la sorgente dell’immagine per un inputtype="image".step: Un numero positivo o una stringa'any'. Specifica la distanza tra valori validi.type: Una stringa. Uno dei tipi di input.width: Una stringa. Specifica la larghezza dell’immagine per un inputtype="image".
Caveats
- Le checkbox necessitano di
checked(odefaultChecked), non divalue(odefaultValue). - Se un input di testo riceve una prop
valuedi tipo stringa, verrà trattato come controllato. - Se una checkbox o un radio button riceve una prop
checkedbooleana, verrà trattato come controllato. - Un input non può essere contemporaneamente controllato e non controllato.
- Un input non può passare da controllato a non controllato (o viceversa) nel corso della sua vita.
- Ogni input controllato necessita di un gestore di eventi
onChangeche aggiorni in modo sincrono il valore sottostante.
Usage
Visualizzare input di tipi diversi
Per visualizzare un input, renderizza un componente <input>. Per impostazione predefinita, sarà un input di testo. Puoi passare type="checkbox" per una checkbox, type="radio" per un radio button, o uno degli altri tipi di input.
export default function MyForm() { return ( <> <label> Text input: <input name="myInput" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" /> </label> <hr /> <p> Radio buttons: <label> <input type="radio" name="myRadio" value="option1" /> Option 1 </label> <label> <input type="radio" name="myRadio" value="option2" /> Option 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Option 3 </label> </p> </> ); }
Fornire un’etichetta per un input
Di solito, posizionerai ogni <input> all’interno di un tag <label>. Questo indica al browser che questa etichetta è associata a quell’input. Quando l’utente clicca sull’etichetta, il browser metterà automaticamente a fuoco l’input. È anche essenziale per l’accessibilità: uno screen reader annuncerà la didascalia dell’etichetta quando l’utente mette a fuoco l’input associato.
Se non puoi annidare <input> in un <label>, associali passando lo stesso ID a <input id> e <label htmlFor>. Per evitare conflitti tra più istanze dello stesso componente, genera un ID del genere con useId.
import { useId } from 'react'; export default function Form() { const ageInputId = useId(); return ( <> <label> Your first name: <input name="firstName" /> </label> <hr /> <label htmlFor={ageInputId}>Your age:</label> <input id={ageInputId} name="age" type="number" /> </> ); }
Fornire un valore iniziale per un input
Puoi specificare facoltativamente il valore iniziale per qualsiasi input. Passalo come stringa defaultValue per gli input di testo. Checkbox e radio button dovrebbero specificare il valore iniziale con il booleano defaultChecked.
export default function MyForm() { return ( <> <label> Text input: <input name="myInput" defaultValue="Some initial value" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Radio buttons: <label> <input type="radio" name="myRadio" value="option1" /> Option 1 </label> <label> <input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Option 3 </label> </p> </> ); }
Leggere i valori degli input all’invio di un form
Aggiungi un <form> attorno ai tuoi input con un <button type="submit"> all’interno. Chiamerà il tuo gestore di eventi <form onSubmit>. Per impostazione predefinita, il browser invierà i dati del form all’URL corrente e aggiornerà la pagina. Puoi sovrascrivere questo comportamento chiamando e.preventDefault(). Leggi i dati del form con new FormData(e.target).
export default function MyForm() { function handleSubmit(e) { // Impedisci al browser di ricaricare la pagina e.preventDefault(); // Leggi i dati del form const form = e.target; const formData = new FormData(form); // Puoi passare formData direttamente come body di fetch: fetch('/some-api', { method: form.method, body: formData }); // Oppure puoi lavorarci come oggetto semplice: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Text input: <input name="myInput" defaultValue="Some initial value" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Radio buttons: <label><input type="radio" name="myRadio" value="option1" /> Option 1</label> <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label> <label><input type="radio" name="myRadio" value="option3" /> Option 3</label> </p> <hr /> <button type="reset">Reset form</button> <button type="submit">Submit form</button> </form> ); }
Controllare un input con una variabile di state
Un input come <input /> è non controllato. Anche se passi un valore iniziale come <input defaultValue="Initial text" />, il tuo JSX specifica solo il valore iniziale. Non controlla quale dovrebbe essere il valore in questo momento.
Per renderizzare un input controllato, passagli la prop value (o checked per checkbox e radio). React forzerà l’input ad avere sempre il value che hai passato. Di solito, lo faresti dichiarando una variabile di state:
function Form() {
const [firstName, setFirstName] = useState(''); // Dichiara una variabile di state...
// ...
return (
<input
value={firstName} // ...forza il valore dell'input a corrispondere alla variabile di state...
onChange={e => setFirstName(e.target.value)} // ... e aggiorna la variabile di state a ogni modifica!
/>
);
}Un input controllato ha senso se avevi già bisogno dello state — ad esempio, per ri-renderizzare la UI a ogni modifica:
function Form() {
const [firstName, setFirstName] = useState('');
return (
<>
<label>
First name:
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</label>
{firstName !== '' && <p>Your name is {firstName}.</p>}
...È utile anche se vuoi offrire più modi per regolare lo state dell’input (ad esempio, cliccando un pulsante):
function Form() {
// ...
const [age, setAge] = useState('');
const ageAsNumber = Number(age);
return (
<>
<label>
Age:
<input
value={age}
onChange={e => setAge(e.target.value)}
type="number"
/>
<button onClick={() => setAge(ageAsNumber + 10)}>
Add 10 years
</button>Il value che passi ai componenti controllati non deve essere undefined o null. Se hai bisogno che il valore iniziale sia vuoto (come nel campo firstName sotto), inizializza la variabile di state a una stringa vuota ('').
import { useState } from 'react'; export default function Form() { const [firstName, setFirstName] = useState(''); const [age, setAge] = useState('20'); const ageAsNumber = Number(age); return ( <> <label> First name: <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </label> <label> Age: <input value={age} onChange={e => setAge(e.target.value)} type="number" /> <button onClick={() => setAge(ageAsNumber + 10)}> Add 10 years </button> </label> {firstName !== '' && <p>Your name is {firstName}.</p> } {ageAsNumber > 0 && <p>Your age is {ageAsNumber}.</p> } </> ); }
Ottimizzare la ri-renderizzazione a ogni battitura
Quando usi un input controllato, imposti lo state a ogni battitura. Se il componente che contiene il tuo state ri-renderizza un albero grande, questo può diventare lento. Ci sono alcuni modi per ottimizzare le prestazioni di ri-renderizzazione.
Ad esempio, supponiamo di iniziare con un form che ri-renderizza tutto il contenuto della pagina a ogni battitura:
function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}Poiché <PageContent /> non dipende dallo state dell’input, puoi spostare lo state dell’input nel suo componente:
function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}
function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}Questo migliora significativamente le prestazioni perché ora solo SignupForm viene ri-renderizzato a ogni battitura.
Se non c’è modo di evitare la ri-renderizzazione (ad esempio, se PageContent dipende dal valore dell’input di ricerca), useDeferredValue ti permette di mantenere l’input controllato reattivo anche nel mezzo di una ri-renderizzazione di grandi dimensioni.
Troubleshooting
Il mio input di testo non si aggiorna quando digito
Se renderizzi un input con value ma senza onChange, vedrai un errore nella console:
// 🔴 Bug: input di testo controllato senza gestore onChange
<input value={something} />value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly.Come suggerisce il messaggio di errore, se volevi solo specificare il valore iniziale, passa defaultValue:
// ✅ Buono: input non controllato con valore iniziale
<input defaultValue={something} />Se vuoi controllare questo input con una variabile di state, specifica un gestore di eventi onChange:
// ✅ Buono: input controllato con onChange
<input value={something} onChange={e => setSomething(e.target.value)} />Se il valore è intenzionalmente in sola lettura, aggiungi una prop readOnly per sopprimere l’errore:
// ✅ Buono: input controllato in sola lettura senza onChange
<input value={something} readOnly={true} />La mia checkbox non si aggiorna quando la clicco
Se renderizzi una checkbox con checked ma senza onChange, vedrai un errore nella console:
// 🔴 Bug: checkbox controllata senza gestore onChange
<input type="checkbox" checked={something} />checked prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultChecked. Otherwise, set either onChange or readOnly.Come suggerisce il messaggio di errore, se volevi solo specificare il valore iniziale, passa defaultChecked:
// ✅ Buono: checkbox non controllata con valore iniziale
<input type="checkbox" defaultChecked={something} />Se vuoi controllare questa checkbox con una variabile di state, specifica un gestore di eventi onChange:
// ✅ Buono: checkbox controllata con onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />Se la checkbox è intenzionalmente in sola lettura, aggiungi una prop readOnly per sopprimere l’errore:
// ✅ Buono: input controllato in sola lettura senza onChange
<input type="checkbox" checked={something} readOnly={true} />Il caret dell’input salta all’inizio a ogni battitura
Se controlli un input, devi aggiornare la sua variabile di state al valore dell’input dal DOM durante onChange.
Non puoi aggiornarla a qualcosa di diverso da e.target.value (o e.target.checked per le checkbox):
function handleChange(e) {
// 🔴 Bug: aggiornare un input a qualcosa di diverso da e.target.value
setFirstName(e.target.value.toUpperCase());
}Non puoi aggiornarla in modo asincrono:
function handleChange(e) {
// 🔴 Bug: aggiornare un input in modo asincrono
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}Per correggere il codice, aggiornalo in modo sincrono a e.target.value:
function handleChange(e) {
// ✅ Aggiornare un input controllato a e.target.value in modo sincrono
setFirstName(e.target.value);
}Se questo non risolve il problema, è possibile che l’input venga rimosso e ri-aggiunto al DOM a ogni battitura. Questo può accadere se stai accidentalmente reimpostando lo state a ogni ri-renderizzazione, ad esempio se l’input o uno dei suoi genitori riceve sempre un attributo key diverso, o se annidi definizioni di componenti (cosa non supportata e fa sì che il componente “interno” venga sempre considerato un albero diverso).
Ricevo un errore: “A component is changing an uncontrolled input to be controlled”
Se fornisci un value al componente, deve rimanere una stringa per tutta la sua vita.
Non puoi passare prima value={undefined} e poi passare value="some string" perché React non saprà se vuoi che il componente sia non controllato o controllato. Un componente controllato dovrebbe sempre ricevere un value di tipo stringa, non null o undefined.
Se il tuo value proviene da un’API o da una variabile di state, potrebbe essere inizializzato a null o undefined. In quel caso, impostalo inizialmente a una stringa vuota (''), oppure passa value={someValue ?? ''} per assicurarti che value sia una stringa.
Allo stesso modo, se passi checked a una checkbox, assicurati che sia sempre un booleano.