Nota bene

Questa pagina è stata tradotta automaticamente e supervisionata da un maintainer. Un’ulteriore revisione da parte della community sarebbe comunque utile. Migliora questa traduzione.

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" />

Vedi altri esempi sotto.

Props

<input> supporta tutte le props comuni degli elementi.

  • formAction: Una stringa o una funzione. Sostituisce l’<form action> padre per type="submit" e type="image". Quando a action viene passato un URL, il form si comporterà come un form HTML standard. Quando a formAction viene 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:

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 input type="file".
  • alt: Una stringa. Specifica il testo alternativo dell’immagine per un input type="image".
  • capture: Una stringa. Specifica il media (microfono, video o fotocamera) catturato da un input type="file".
  • autoComplete: Una stringa. Specifica uno dei possibili comportamenti di autocomplete.
  • autoFocus: Un booleano. Se true, 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. Se true, l’input non sarà interattivo e apparirà attenuato.
  • children: <input> non accetta children.
  • form: Una stringa. Specifica l’id del <form> a cui appartiene questo input. Se omesso, è il form padre più vicino.
  • formAction: Una stringa. Sostituisce l’<form action> padre per type="submit" e type="image".
  • formEnctype: Una stringa. Sostituisce l’<form enctype> padre per type="submit" e type="image".
  • formMethod: Una stringa. Sostituisce il <form method> padre per type="submit" e type="image".
  • formNoValidate: Una stringa. Sostituisce il <form noValidate> padre per type="submit" e type="image".
  • formTarget: Una stringa. Sostituisce il <form target> padre per type="submit" e type="image".
  • height: Una stringa. Specifica l’altezza dell’immagine per type="image".
  • list: Una stringa. Specifica l’id del <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" e type="email".
  • name: Una stringa. Specifica il nome di questo input che viene inviato con il form.
  • onChange: Una funzione gestore di Event. 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’evento input del browser.
  • onChangeCapture: Una versione di onChange che scatta nella fase di capture.
  • onInput: Una funzione gestore di Event. Scatta immediatamente quando il valore viene modificato dall’utente. Per ragioni storiche, in React è idiomatico usare onChange al suo posto, che funziona in modo simile.
  • onInputCapture: Una versione di onInput che scatta nella fase di capture.
  • onInvalid: Una funzione gestore di Event. Scatta se un input non supera la validazione all’invio del form. A differenza dell’evento invalid integrato, l’evento React onInvalid fa bubbling.
  • onInvalidCapture: Una versione di onInvalid che scatta nella fase di capture.
  • onSelect: Una funzione gestore di Event. Scatta dopo che la selezione all’interno dell’<input> cambia. React estende l’evento onSelect per scattare anche con selezione vuota e durante le modifiche (che possono influenzare la selezione).
  • onSelectCapture: Una versione di onSelect che scatta nella fase di capture.
  • pattern: Una stringa. Specifica il pattern che il value deve rispettare.
  • placeholder: Una stringa. Visualizzata con un colore attenuato quando il valore dell’input è vuoto.
  • readOnly: Un booleano. Se true, l’input non è modificabile dall’utente.
  • required: Un booleano. Se true, 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 input type="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 input type="image".

Caveats

  • Le checkbox necessitano di checked (o defaultChecked), non di value (o defaultValue).
  • Se un input di testo riceve una prop value di tipo stringa, verrà trattato come controllato.
  • Se una checkbox o un radio button riceve una prop checked booleana, 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 onChange che 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>
  );
}

Nota bene

Assegna un name a ogni <input>, ad esempio <input name="firstName" defaultValue="Taylor" />. Il name che hai specificato verrà usato come chiave nei dati del form, ad esempio { firstName: "Taylor" }.

Insidia

Per impostazione predefinita, un <button> all’interno di un <form> senza attributo type lo invierà. Può essere sorprendente! Se hai un tuo componente React Button personalizzato, considera l’uso di <button type="button"> invece di <button> (senza type). Poi, per essere esplicito, usa <button type="submit"> per i pulsanti che devono inviare il 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>
      }
    </>
  );
}

Insidia

Se passi value senza onChange, sarà impossibile digitare nell’input. Quando controlli un input passandogli un value, lo forzi ad avere sempre il valore che hai passato. Quindi se passi una variabile di state come value ma dimentichi di aggiornare quella variabile di state in modo sincrono durante il gestore di eventi onChange, React ripristinerà l’input dopo ogni battitura al value che hai specificato.


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} />
Console
You provided a 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} />
Console
You provided a 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)} />

Insidia

Devi leggere e.target.checked anziché e.target.value per le checkbox.

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.