Forms
These docs are old and wonβt be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React and include live examples:
Gli elementi HTML form
funzionano in un modo differente rispetto agli altri elementi DOM in React, la motivazione sta nel fatto che gli elementi form mantengono naturalmente uno stato interno. Ad esempio, questo form in puro HTML accetta un singolo nome:
<form>
<label>
Nome:
<input type="text" name="nome" />
</label>
<input type="submit" value="Submit" />
</form>
Questo form si comporta come di consueto, facendo navigare lβutente in una nuova pagina quando viene inviato. In React, se vuoi avere lo stesso comportamento, non cβΓ¨ bisogno di fare alcuna modifica. Ad ogni modo, potrebbe essere piΓΉ conveniente avere una funzione JavaScript che gestisce lβinvio del form e che ha accesso ai dati inseriti dallβutente. La tecnica standard con cui si puΓ² ottenere ciΓ² prende il nome di βcomponenti controllatiβ.
Componenti Controllati
In HTML, gli elementi di un form come <input>
, <textarea>
e <select>
mantengono tipicamente il proprio stato e lo aggiornano in base allβinput dellβutente. In React, lo stato mutabile viene tipicamente mantenuto nella proprietΓ state
dei componenti e viene poi aggiornato solo mediante setState()
.
Possiamo combinare le due cose rendendo lo state in React la βsingola fonte attendibileβ (SSOT). Possiamo poi fare in modo che il componente React che renderizza il form controlli anche cosa succede allβinterno del form in risposta agli input dellβutente. In un form, un elemento di input il cui valore Γ¨ controllato da React in questo modo viene chiamato βcomponente controllatoβ.
Ad esempio, se vogliamo far sΓ¬ che lβesempio precedente registri il nome inserito, possiamo riscrivere il form sotto forma di componente controllato:
class FormNome extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('E\' stato inserito un nome: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}> <label>
Nome:
<input type="text" value={this.state.value} onChange={this.handleChange} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}
Dato che lβattributo value
viene impostato nel nostro elemento form, il valore visualizzato sarΓ sempre this.state.value
, rendendo lo stato in React lβunica fonte di dati attendibile. Dato che la funzione handleChange
viene eseguita ad ogni battitura per aggiornare lo stato di React, il valore visualizzato verrΓ aggiornato man mano che lβutente preme i tasti.
Con un componente controllato, il valore dellβinput viene sempre controllato dallo stato di React. Anche se ciΓ² comporta la battitura di piΓΉ codice, permette il passaggio del valore anche ad altri elementi della UI, o di resettarlo da altri event handlers.
Il Tag Textarea
In HTML, lβelemento <textarea>
definisce il testo in esso contenuto con i suoi elementi figli:
<textarea>
Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura
chΓ© la diritta via era smarrita.
</textarea>
In React, invece, <textarea>
utilizza lβattributo value
. Per questo, un form che utilizza una <textarea>
puΓ² essere scritto in modo molto simile a come verrebbe scritto se utilizzasse un semplice input di una sola riga:
class FormTema extends React.Component {
constructor(props) {
super(props);
this.state = { value: 'Per favore scrivi un tema riguardo il tuo elemento DOM preferito.' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('Un tema Γ¨ stato inviato: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Tema:
<textarea value={this.state.value} onChange={this.handleChange} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}
Nota come this.state.value
viene inizializzato nel costruttore, cosìcche la casella di testo è inizializzata con del testo al suo interno.
Il Tag Select
In HTML, <select>
crea una lista a discesa. Per esempio, questo HTML crea una lista a discesa di gusti:
<select>
<option value="pompelmo">Pompelmo</option>
<option value="limone">Limone</option>
<option selected value="cocco">Cocco</option>
<option value="mango">Mango</option>
</select>
Nota come lβopzione Cocco venga preselezionata grazie allβattributo selected
. React, piuttosto che usare lβattributo selected
, usa lβattributo value
dellβelemento radice select
. CiΓ² facilita le cose in un componente controllato in quanto bisogna aggiornare lo stato in un posto solo. Ad esempio:
class FormGusti extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'cocco'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('Il tuo gusto preferito Γ¨: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Seleziona il tuo gusto preferito:
<select value={this.state.value}
onChange={this.handleChange}>
<option value="pompelmo">Pompelmo</option>
<option value="limone">Limone</option>
<option value="cocco">Cocco</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Ricapitolando, ciò fa sì che <input type="text">
, <textarea>
e <select>
funzionino in modo molto simile - tutti accettano un attributo value
che puoi utilizzare per implementare un componente controllato.
Nota bene
Puoi passare un array nellβattributo
value
, permettendoti di selezionare opzioni multiple in un tagselect
:<select multiple={true} value={['B', 'C']}>
Il Tag Input File
In HTML, un <input type="file">
permette allβutente di selezionare uno o piΓΉ file da disco e di inviarli al server o manipolarli in JavaScript mediante le File API.
<input type="file" />
Dato che il suo valore Γ¨ in sola-lettura, Γ¨ un componente non controllato in React. Riprenderemo il discorso riguardo questo ed altri componenti non controllati in seguito.
Gestione di Input Multipli
Quando devi gestire diversi elementi input
, puoi aggiungere un attributo name
ad ognuno di essi e far sì che la funzione handler controlli cosa fare in base al valore di event.target.name
.
Ad esempio:
class Prenotazione extends React.Component {
constructor(props) {
super(props);
this.state = {
presente: true,
numeroOspiti: 2,
};
this.handleInputChange = this.handleInputChange.bind(
this
);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value, });
}
render() {
return (
<form>
<label>
SarΓ presente:
<input
name="presente"
type="checkbox"
checked={this.state.presente}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Numero di ospiti:
<input
name="numeroOspiti"
type="number"
value={this.state.numeroOspiti}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
Nota come abbiamo utilizzato la sintassi ES6 computed property name (βnome proprietΓ calcolatoβ) per aggiornare la rispettiva chiave nello stato a seconda dellβattributo name
dellβinput:
this.setState({
[name]: value});
Il che in ES5 corrisponde al codice:
var statoParziale = {};
statoParziale[name] = value;this.setState(statoParziale);
Inoltre, dato che setState()
unisce uno stato parziale nello stato corrente automaticamente, dobbiamo chiamarla con le sole parti modificate.
Valore Null in Input Controllati
Specificare la prop value
in un componente controllato fa sΓ¬ che lβutente possa cambiare lβinput solo quando lo desideri. Se hai specificato un value
ma lβinput Γ¨ ancora editabile, potresti aver accidentalmente impostato value
come undefined
o null
.
Il codice seguente lo dimostra. (Lβinput Γ¨ inizialmente bloccato ma diventa editabile dopo un secondo)
ReactDOM.createRoot(mountNode).render(<input value="ciao" />);
setTimeout(function() {
ReactDOM.createRoot(mountNode).render(<input value={null} />);
}, 1000);
Alternative ai Componenti Controllati
Utilizzare componenti controllati puΓ² sembrare laborioso a volte, soprattutto perchΓ© Γ¨ necessario scrivere un event handler per ogni modo in cui i tuoi dati possono cambiare e perchΓ© si deve collegare lo stato di tutti gli input a quello di un componente React. Il tutto diventa particolarmente noioso quando bisogna convertire progetti preesistenti in React, o integrare unβapplicazione React con una libreria non-React. In queste situazioni, si potrebbe ricorrere ai componenti non controllati, una tecnica alternativa per implementare forms ed i relativi campi di input.
Soluzioni Chiavi In Mano
Se stai cercando una soluzione che include la validazione dei dati, il tener traccia dei campi visitati e la sottomissione del form, Formik Γ¨ una delle scelte popolari. Comunque, si basa sugli stessi principi dei componenti controllati e della gestione dello stato β ecco perchΓ© Γ¨ bene essere familiari con questi concetti.