React, l’interfaccia utente costruita componente su componente

28 giugno 2014

Creare componenti con React

Quando si progetta una interfaccia utente, è necessario immaginarla come il risultato della composizione di tanti elementi, partendo dal più grande che al suo interno contiene via via quelli più piccoli. Vediamo quindi come creare i componenti, gli elementi fondamentali da combinare per realizzare l’interfaccia.

Rendering di un componente

È grazie a JavaScript che possiamo definire la struttura di un componente, nella quale indichiamo:

  1. il DOM da generare per rappresentarlo sulla pagina (usando opzionalmente la sintassi JSX);
  2. il comportamento, ovvero come esso reagisce alle azioni dell’utente.

Inoltre il componente React rappresenta una vera e propria “macchina a stati”, ossia indica le variabili che esprimono il suo stato iniziale che possono essere alterate.

Un sempice esempio ci sarà d’aiuto: realizziamo il più semplice dei componenti, il classico “Hello world”.

var HelloReact = React.createClass({ 

	render : function() { 
		return <div>Hello React!</div>; 
	} 
});

La funzione React.createClass consente di dichiarare un nuovo componente e di definire tutte le sue caratteristiche.

Nell’esempio, la proprietà render dell’oggetto passato viene valorizzata con una funzione in grado di restituire il markup che rappresenta il componente sulla pagina: in questo caso, apparirà un semplice <div> con la scritta "Hello React!".

Nella logica della funzione render(), la mescolanza di JavaScript e HTML viene resa possibile dalla sintassi JSX, di cui abbiamo già parlato. Siccome la funzione potrà avere sempre uno e un solo valore di ritorno, questa scrittura non è possibile:

var HelloReact = React.createClass({ 
	render : function() { 
		return 
		<p>Questo è il primo esempio</p> 
		<div>Hello React!</div>; 
	} 
});

Ogni tag viene tradotto da JSX in un oggetto, quindi nel codice sopra ne stiamo restituendo due. Per poter restituire componenti multipli, è sufficiente che questi siano inseriti all’interno di un unico “contenitore”, dove possiamo metterne quanti vogliamo, come illustrato in questo esempio:

var HelloWorld = React.createClass({ 

	render : function() { 
		return <div><p>Questo è il primo esempio:</p> <span>Hello React!</span></div>; 
	} 
});

Per visualizzare il componente “HelloWorld” che abbiamo appena creato all’interno della nostra pagina, occorre richiamare la funzione React.renderComponent:

React.renderComponent( 
	<HelloWorld />, 
	document.body 
);

La funzione renderComponent() prende due parametri: il componente React che deve essere visualizzato nella pagina e l’elemento del DOM che lo ospiterà (in questo caso, si tratta del <body> della pagina); anche qui, il componente può essere specificato utilizzando ancora la sintassi JSX.

Proprietà e stato di un componente

Ogni componente rappresenta un modello replicabile di markup che deve essere inserito nella pagina per fungere da vista per un singolo dato o un insieme di dati.

Nella fase di creazione di un componente tramite la funzione React.createClass(), possiamo definire un insieme di proprietà per passare al componente valori da inserire all’interno del template HTML generato in fase di rendering, oppure per influenzarne la logica interna di funzionamento. I valori delle proprietà sono contenuti nel campo props.

Ecco il codice di esempio di un componente che visualizza un saluto all’utente consentendo di specificare dall’esterno il nome della persona valorizzando la proprietà “name”:

var GreetingMessage = React.createClass({ 

	render: function() { 
		return <div>Ciao <strong>{this.props.name}</strong></div>; 
	} 
});

Questo è invece il codice che effettua il rendering del componente GreetingMessage valorizzando la proprietà:

React.renderComponent(<GreetingMessage name="Marco" />, document.body);

Una delle prerogative di React è quella di poter generare gli elementi del DOM in base ai dati specificati e, qualora essi subiscano un cambiamento, “reagire” aggiornandoli per riflettere tali cambiamenti. Tuttavia, le proprietà sono immutabili, ovvero non è possibile modificare i valori delle proprietà impostati inizialmente: per queste esigenze è possibile ricorrere allo stato del componente.

Analogamente alle proprietà, lo stato di un componente è un oggetto (memorizzato nel campo state) che contiene valori utilizzabili durante il rendering e modificabili all’occorrenza attraverso funzioni specifiche del framework che consentono a React di occuparsi – se necessario – dell’aggiornamento degli elementi del DOM legati al nuovo stato, nel modo più veloce e performante possibile.

Analizziamo il seguente esempio di codice che implementa un pulsante “Mi piace” e lo inserisce nel <body> della pagina:

/** @jsx React.DOM */ 

var LikeButton = React.createClass({ 

	getInitialState: function() { 
		return {liked: false}; 
	}, 
	
	handleClick: function(event) { 
		this.setState({liked: !this.state.liked}); 
	}, 

	render: function() { 
		var text = this.state.liked ? 'piace' : 'NON piace'; 
		return ( 
			<p onClick={this.handleClick}> 
			A te {text} questo esempio. Clicca per modificare. 
			</p> 
		); 
	} 
}); 

Oltre alla funzione render() già vista, possiamo notare la presenza della funzione getInitialState(), che ha lo scopo di restituire l’oggetto che rappresenta lo stato iniziale del componente; nell’esempio sopra, viene creato e restituito un oggetto che contiene un campo booleano, “like”, che viene impostato a “true” se l’esempio ci piace oppure a “false” in caso contrario.

La funzione handleClick() è un callback che intercetta l’azione di clic con il mouse sul testo del componente per variarne lo stato: attraverso l’uso della funzione setState(), impostiamo i valori dello stato aggiornato del componente communtando il valore booleano del campo “liked” e informando contemporaneamente React della possibile necessità di aggiornare l’interfaccia rappresentata dal componente nella pagina.

La funzione render() restituisce l’elemento HTML (un semplice paragrafo <p>) da inserire nella pagina, utilizzando una dicitura differente in base alla preferenza espressa e memorizzata in una variabile temporanea (“text”); è presente inoltre l’associazione della funzione di callback handleClick() all’evento di clic sul paragrafo, affinché sia possibile intercettarlo eseguendo la commutazione del nostro apprezzamento.

Gestione degli eventi

La gestione degli eventi è una funzionalità imprescindibile per qualsiasi framework progettato per la creazione di applicazioni Web dinamiche e interattive, e ciò vale ovviamente anche per React.

Per rispondere alle azioni dell’utente, come abbiamo visto nell’esempio del “LikeButton”, React consente di associare funzioni di callback agli eventi supportati dagli elementi HTML, specificandone il nome usando la convenzione cosiddetta “camelCase” (es. per l’evento onclick, si usa l’attributo onClick).

Anche se potrebbe sembrare da una prima lettura del codice, React non aggancia ogni funzione di callback al singolo elemento del DOM, bensì utilizza un proprio gestore unificato degli eventi che si verificano nella pagina (event listener), propagando l’esecuzione al callback appropriato in base all’azione specifica e all’elemento su cui è stata rilevata l’interazione.

Attraverso un meccanismo di mappatura interna delle funzioni di calback e a diverse ottimizzazioni, React garantisce una gestione efficiente, performante e ottimale degli eventi, semplificando inoltre la scrittura del codice che può essere fatta utilizzando le convenzioni abituali.

Se vuoi aggiornamenti su React, l'interfaccia utente costruita componente su componente inserisci la tua e-mail nel box qui sotto:
UI
 
X
Se vuoi aggiornamenti su React, l'interfaccia utente costruita componente su componente

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy