Dopo aver costruito il tuo componente, potresti trovarti nella situazione di volere invocare dei metodi sulle istanze di componenti restituite da render()
. Nella maggior parte dei casi, questo non è necessario poiché il flusso di dati reattivo assicura sempre che le proprietà più recenti siano assegnate a ciascun figlio prodotto da render()
. Tuttavia, esistono dei casi in cui potrebbe essere necessario o desiderabile, quindi React fornisce una via d'uscita conosciuta come refs
. Queste refs
(riferimenti) sono particolarmente utili quando vuoi: trovare il markup DOM prodotto da un componente (ad esempio, per posizionarlo in modo assoluto), usare componenti React in una più ampia applicazione non-React, oppure effettuare la transizione del tuo codice a React.
Vediamo come ottenere un ref, e quindi passiamo ad un esempio completo.
Da non confondersi con il metodo render()
che definisci sul tuo componente (il quale restituisce un elemento DOM virtuale), ReactDOM.render() restituisce un riferimento all'istanza di supporto del tuo componente (o null
per i componenti privi di stato).
var myComponent = ReactDOM.render(<MyComponent />, myContainer);
Tieni a mente, tuttavia, che JSX non restituisce un'istanza di un componente! È solo un ReactElement: una rappresentazione leggera che istruisce React su come il componente montato debba apparire.
var myComponentElement = <MyComponent />; // Questo è un semplice ReactElement.
// Qui va del codice...
var myComponentInstance = ReactDOM.render(myComponentElement, myContainer);
myComponentInstance.doSomething();
Nota:
Questo deve essere usato soltanto al livello più alto. All'interno dei componenti, lascia che i tuoi
props
estate
gestiscano la comunicazione con i componenti figli, oppure utilizza uno degli altri metodi per ottenere un ref (attributo stringa o callback).
React supporta un attributo speciale che puoi assegnare a qualsiasi componente. L'attributo ref
può essere una funzione callback, che sarà eseguita immediatamente dopo che il componente viene montato. Il componente referenziato sarà passato come parametro, e la funzione callback può utilizzare il componente immediatamente, oppure conservarne un riferimento per un uso successivo, o entrambe.
È semplice come aggiungere un attributo ref
a qualsiasi cosa restituita da render
usando una funzione freccia di ES6:
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
oppure usando una funzione freccia ES6:
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
Nota che quando il componente referenziato viene smontato e quando il valore di ref cambia, ref sarà chiamata con null
come argomento. Ciò impedisce i memory leak nel caso in cui l'istanza venga conservata, come nel primo esempio. Nota che quando assegni il valore di ref a un'espressione di funzione in linea come negli esempi precedenti, React vede un oggetto funzione diverso ogni volta e pertanto in occasione di ciascun aggiornamento, ref verrà chiamata con null
immediatamente prima di essere chiamata con l'istanza del componente.
Puoi accedere al nodo DOM del componente direttamente chiamando ReactDOM.findDOMNode(argomentoDellaTuaCallback)
.
React supporta anche l'uso di una stringa (anziché una callback) come proprietà ref su qualsiasi componente, sebbene allo stato attuale questo approccio sia quasi esclusivamente superato.
Assegna un attributo ref
a qualsiasi cosa restituita da render
come:
<input ref="myInput" />
Altrove nel codice (tipicamente in un gestore di eventi), accedi all'istanza di supporto tramite this.refs
come segue:
this.refs.myInput
Puoi accedere direttamente al nodo DOM del componente chiamando ReactDOM.findDOMNode(this.refs.myInput)
.
Per ottenere un riferimento a un componente React, puoi usare this
per ottenere il componente React attuale, oppure usare un ref per ottenere un riferimento a un componente di tua proprietà. Il funzionamento è il seguente:
var MyComponent = React.createClass({
handleClick: function() {
// Assegna il focus esplicitamente al campo di testo usando l'API DOM nativa.
this.myTextInput.focus();
},
render: function() {
// L'attributo ref aggiunge un riferimento al componente a this.refs quando
// il componente viene montato
return (
<div>
<input type="text" ref={(ref) => this.myTextInput = ref} />
<input
type="button"
value="Assegna il focus al campo di testo"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
In questo esempio, otteniamo un riferimento all'istanza di supporto del campo di testo e vi invochiamo il metodo focus()
quando il bottone viene cliccato.
Per componenti compositi, il riferimento si riferisce a un'istanza della classe del componente, quindi puoi invocare ogni metodo definito in tale classe. Se devi accedere al nodo DOM sottostante per il componente, puoi usare ReactDOM.findDOMNode.
I riferimenti ref
sono la maniera corretta di inviare un messaggio a una precisa istanza di un figlio in una maniera che sarebbe impraticabile attraverso le normali proprietà props
e state
di React. Tuttavia, esse non dovrebbero essere la tua astrazione principale per far fluire i dati attraverso la tua applicazione. In modo predefinito, usa il flusso dati di React e utilizza i ref
per casi d'uso che sono intrinsecamente non reattivi.
this.refs.myTypeahead.reset()
).<input />
accedendo il suo nodo DOM sottostante attraverso ReactDOM.findDOMNode(this.refs.myInput)
. I riferimenti sono uno degli unici metodi praticabili per fare ciò in maniera affidabile.this.refs['myRefString']
se il tuo ref è stato definito come ref="myRefString"
.state
debba trovarsi. Spesso ti accorgerai che il luogo corretto per "possedere" lo stato si trova a un livello più alto nella gerarchia. Posizionare lì lo stato spesso elimina ogni necessità di usare i ref
per "fare accadere qualcosa" – al contrario, il flusso dei dati solitamente otterrà lo scopo desiderato.