React Native: la Piattaforma Open Source di Meta

React Native è una piattaforma open source per applicazioni mobili sviluppata da Facebook/Meta e basata su Javascript. È utilizzata per lo sviluppo di app mobili cross-platform per iOS e Android ed è diventata sempre più popolare negli ultimi anni.

Alcune delle applicazioni più famose e utilizzate quotidianamente come Facebook, Instagram, Skype, Pinterest, UberEats sono state sviluppate utilizzando React Native.

I benefici di React Native

React Native permette agli sviluppatori di codificare una sola volta e di implementarlo su diverse piattaforme, consentendo un risparmio di tempo e risorse. Essendo basato su JavaScript e React, tecnologie già ampiamente utilizzate, facilita l’apprendimento e l’uso di React Native da parte degli sviluppatori.

Una delle sue peculiarità principali è l’abilità di convertire direttamente il codice in codice nativo, permettendo un miglioramento delle performance e della rapidità. Le applicazioni React Native operano con la stessa scorrevolezza di applicazioni create attraverso Java e Kotlin su dispositivi Android e di applicazioni create attraverso Swift su dispositivi iOS.

L’uso del codice nativo consente di utilizzare al massimo le funzionalità del dispositivo come, per esempio, la camera, l’accelerometro o il GPS. Questo permette agli sviluppatori di produrre applicazioni mobili altrettanto efficaci e ricche di funzionalità come le applicazioni native. In aggiunta a ciò, React Native permette di creare applicazioni seguendo gli stessi principi dello sviluppo web, focalizzandosi su componenti riutilizzabili e architettura modulare.

Differenze tra React.js e React Native

React e React Native sono tecnologie differenti tra loro nonostante condividano la sintassi tipica di Javascript: il primo è una libreria pensata e strutturata per sviluppare applicazioni web mentre il secondo è un framework specifico per le applicazioni mobile. In cosa si traduce questa differenza in termini di codice? Entrambi fanno uso di un virtual DOM, che consente di migliorare le performance e avere aggiornamenti dell’interfaccia utente più rapidi.

Tuttavia, mentre alla base di React c’è l’uso di tag ed elementi tipici del linguaggio HTML, React Native utilizza componenti nativi, che permettono di sfruttare al meglio le potenzialità dei dispositivi. Per questo motivo il tag <div> di React corrisponde a <View> in React Native; il tag <p> di React corrisponde a <Text> in React Native; il tag <img> di React corrisponde a <Image> in React Native e così via.

Le differenze sussistono anche per la modalità di styling: React usa dei file CSS che vengono importati e applicati nei corrispondenti componenti, mentre in React Native lo stile si applica passando delle proprietà all’interno di oggetti Javascript.

Come creare un’app in React Native

Prima di tutto, assicuriamoci di avere installato Node.js, necessario per compilare il codice Javascript del nostro progetto React Native.

Per facilitare l’esecuzione dell’app, faremo uso di Expo. Questo è un framework che offre una serie di strumenti e servizi sviluppati attorno a React Native, permettendo di sviluppare e compilare velocemente sia su iOS che su Android a partire dallo stesso codice sorgente.

  • Fase 1: eseguiamo l’installazione della Expo CLI utilizzando il comando npm install -g expo-cli
  • Fase 2: apriamo il terminale, ci spostiamo nella directory dove desideriamo generare il progetto React Native. Implementiamo il comando npx create-expo-app nome_progetto, inserendo il nome che abbiamo scelto per il nostro progetto.
  • Fase 3: spostandoci all’interno della directory appena generata, possiamo osservare i file che compongono il progetto. Per avviarlo, eseguiamo il comando npx expo start o lo script corrispondente alla voce “start” nel file package.json creato nella fase 2.
  •  

Nel terminale del nostro editor dovremmo visualizzare i seguenti log ➡️

Dalla configurazione di default Using Development Build, è possibile passare alla modalità Using Expo Go, cliccando su “s”. Questa modalità consente di controllare i progressi del nostro lavoro in tempo reale, utilizzando un qrCode da scannerizzare con il dispositivo su cui si desidera testare l’app.

Cliccando su “a”, si può visualizzare o ricaricare l’app su un emulatore creato con Android Studio o su un telefono Android con Expo Go installato e connesso alla stessa rete Wi-Fi del computer. Per i dispositivi iOS, si può ottenere lo stesso effetto cliccando su “i”. 

Altre funzionalità che facilitano il processo di sviluppo includono, per esempio: “j” per il debugger e “r” per un aggiornamento rapido dell’app dopo la modifica del file.

Componenti core e componenti custom

React Native offre una serie di componenti nativi fondamentali, pronti per essere utilizzati, che possiamo impiegare nelle nostre applicazioni: i cosiddetti componenti principali o componenti core. Ne esistono di vari tipi e il primo passo quando desideriamo implementare una qualsiasi funzione è capire quali componenti principali potrebbero essere necessari.

Per questo scopo, è utile consultare la documentazione di React Native. È molto dettagliata e piena di esempi che mostrano come usare i componenti e quali proprietà devono essere passate. La tabella seguente elenca alcuni dei componenti principali più rilevanti e utilizzati in ogni progetto, con le loro corrispondenti versioni su Android e iOS:

View: l’esempio più generale di container, cioè di componente che contiene altri componenti. Accetta una serie di parametri che consentono di gestire al meglio la visualizzazione degli elementi al suo interno o di rispondere a eventuali azioni dell’utente, come un semplice tocco o un tocco prolungato.

Text: il componente fondamentale per visualizzare stringhe di testo nella nostra interfaccia. E’ possibile personalizzare il font utilizzato, il colore, la dimensione, lo spessore del testo, la spaziatura tra le linee e altro ancora.

Image: componente per visualizzare immagini nella nostra interfaccia. Le immagini possono essere possono essere prese sia da una cartella locale all’interno del nostro progetto, sia dal web. Inoltre sono supportati tutti i principali formati per le immagini, tra i quali .jpg, .jpeg, .png e .svg

ScrollView : quando il contenuto della nostra interfaccia supera le dimensioni fisiche dello schermo, è fondamentale dare modo all’utente di scorrere attraverso il movimento delle dita. Il componente ScrollView è un container pensato per questo scopo specifico, permette di rendere “scrollabile” tutta l’interfaccia o solamente una porzione a seconda delle nostre esigenze.

TextInput: componente che permette all’utente di inserire un testo all’interno di un campo, come se ne trovano nelle schermate di login oppure in un form da compilare.

Combinando tra loro i componenti core, possiamo definire dei componenti personalizzati o custom. 
L’idea è molto semplice: anziché copiare più e più volte lo stesso frammento di codice, è sufficiente scriverlo una volta e richiamarlo dove necessario. Questo concetto di riusabilità del codice giova sia all’ottimizzazione delle prestazioni, sia alla facilità di gestione di eventuali modifiche. Vediamo un esempio:

In questo codice possiamo identificare due componenti Custom, Cat e CatList.

Notiamo che entrambi impiegano la funzione Return e che ciò che viene restituito è un singolo componente, di solito una View. È concettualmente errato restituire due componenti View allo stesso livello, ma è fattibile se una View è contenuta nell’altra.

Avere definito il componente Cat ci permette di riutilizzarlo all’interno di CatList senza la necessità di duplicare il codice: i componenti Custom possono naturalmente includere altri componenti Custom. In pratica, posso usare il Tag Cat con la stessa sintassi dei componenti Core.

Uno degli elementi fondamentali di React Native, condiviso con React, è l’impiego del JSX: questa specifica sintassi che permette di scrivere Tag all’interno del codice Javascript. Proprio perché è un’estensione di Javascript, otteniamo la capacità di inserire variabili direttamente nei nostri tag, purché siano racchiuse tra parentesi graffe:

Ecco come la variabile Javascript name diventa accessibile all’interno del componente Text!

I concetti di props e State

Il codice che abbiamo scritto fino ad ora ci permette di utilizzare una variabile per il nome del gatto, ma finché è definita nel componente Cat, non abbiamo modo di rendere il componente dinamico. È qui che le “props” entrano in gioco.

Props è un’abbreviazione di Properties, cioè proprietà. Queste permettono di personalizzare un componente figlio con informazioni fornite da un componente padre. In termini tecnici, Props è un oggetto Javascript disponibile per ogni elemento e nel componente figlio possiamo accedere alle chiavi di questo oggetto. Le props vengono utilizzate per quelle proprietà che rimarranno costanti per tutta la durata del ciclo di vita del componente. Ecco un esempio:

Inserendo il parametro Name per ciascun elemento Cat, abbiamo effettivamente aggiunto una chiave all’oggetto Javascript Props. Trasmettendo questo oggetto come parametro al componente Cat, tutti i componenti figli possono accedere alla chiave tramite props.name, che è esattamente ciò che succede nel componente Text alla riga 12. In questo modo, il valore associato alla chiave Name viene utilizzato correttamente, permettendo di visualizzare sullo schermo i vari nomi dei gatti.

Questo processo non è affatto sorprendente. Quando desideriamo inserire un’immagine, passiamo un parametro Source al componente Image, che è stato impostato nella libreria react-native per accettare tale proprietà: il processo è identico e funziona ogni volta che desideriamo trasmettere delle proprietà immutabili. 

Lo stato interviene quando dobbiamo gestire informazioni che variano nel tempo o che derivano dall’interazione dell’utente. Lo stato offre memoria ai nostri componenti e può essere considerato come un deposito di dati.

Mentre le Props sono trasferite da un componente all’altro, lo stato è una variabile che esiste unicamente all’interno di un componente; non può essere letta o alterata al di fuori di quel componente se non tramite funzioni di Callback. Funziona in maniera molto simile a una variabile dichiarata localmente in una funzione Javascript: non è raggiungibile al di fuori dello Scope della funzione.

In questo esempio, introduciamo uno stato nel componente Cat utilizzando la variabile booleana felice, che viene inizialmente impostata su false. Questa variabile rappresenta le interazioni dell’utente con l’interfaccia: quando l’utente fa clic sulla foto del gatto, viene invocato il metodo setFelice che alterna il valore booleano da false a true e viceversa.

Dato che sia l’immagine che il testo incorporano un operatore ternario che dipende dalla variabile felice, la visualizzazione si aggiorna di conseguenza. È fondamentale sottolineare che ciascuno dei 3 componenti Cat ha il proprio stato e non incide su quello degli altri due. 

Potrebbe apparire insolito che la variabile ‘felice’ possa essere alterata nonostante sia stata definita con la parola chiave const. In realtà, per gestire le modifiche di stato, è necessaria una sintassi molto specifica: si deve dichiarare un Array di due elementi, il primo rappresenta la variabile di stato (felice) mentre il secondo rappresenta il metodo per alterare il valore della variabile (setFelice). A questo Array si assegna il valore della funzione useState del modulo react, a cui si fornisce come argomento il valore predefinito dello stato (false). La variabile ‘felice’ può essere modificata solo tramite il metodo setFelice e qualsiasi altro tentativo causerà un errore.

Come importare componenti e funzionalità in React Native

Abbiamo citato la funzione useState del modulo react, una funzione disponibile se abbiamo installato il modulo react nel nostro progetto, ma che deve essere importata in modo appropriato. Ci sono principalmente due metodi per importare delle funzioni.

Consideriamo il primo caso:

Si tratta di due esempi differenti dello stesso modello. Importiamo la funzione useState da react e i componenti Text, View, Image, Stylesheet dalla libreria react-native. Nessuno di questi è stato impostato come export predefinito del relativo modulo, pertanto è essenziale indicarli tra parentesi graffe e utilizzare lo stesso nome con cui sono stati definiti nel modulo react-native. 

Il secondo caso:

Qui stiamo importando il componente CatList , definito nel file Guida, all’interno di un altro file del nostro progetto.  E’ possibile omettere le parentesi graffe se l’oggetto che stiamo importando è stato configurato come export di default nel file Guida: questo è vero come riporta la dicitura export default davanti alla definizione della funzione CatList.

Una caratteristica di questo import è che NON è importante il nome utilizzato. Ogni modulo può avere al più un valore di default; dunque il nome perde il ruolo di fattore discriminante, com’era invece nel caso precedente. Potremmo scrivere CatLista, ListaDiGatti nella riga di import e utilizzare lo stesso componente con il nuovo nome senza riscontrare errori. Tuttavia è buona norma usare lo stesso nome scelto nel file di export per evitare confusioni.

Se volessimo importare Cat, in questo momento non sarebbe possibile perché non è stato configurato per essere esportato: manca infatti la parola chiave export davanti alla definizione della funzione Cat. Dopo averla aggiunta, sarà possibile importare Cat ma solo tra parentesi graffe e con il nome esatto con il quale è stato definito nel modulo Guida:

Personalizzazione dello stile del progetto

Esistono principalmente due metodi per gestire lo stile nel nostro progetto React Native: il primo consiste nell’utilizzare direttamente la proprietà style nei nostri componenti, il cui valore sarà un oggetto. Il secondo metodo è più sintetico, e prevede l’uso del metodo create del componente Stylesheet, al quale si passa un oggetto Javascript come argomento: le chiavi saranno riferite dai nostri componenti, mentre i valori sono oggetti Javascript che contengono le proprietà che desideriamo applicare.

In questo modo, per applicare lo stile corrispondente alla chiave container, è sufficiente passare la prop style = {styles.container} al componente pertinente.

Ci sono numerosi benefici di questo metodo: prima di tutto, il codice dei nostri componenti rimane più ordinato e non viene appesantito dalle informazioni di stile, inoltre la stessa chiave può essere applicata a più componenti. L’oggetto Stylesheet risiede all’interno del singolo file, quindi ogni file può avere il suo Stylesheet con chiavi che hanno lo stesso nome senza causare alcuna interferenza (un problema che può invece sorgere con i .css in un progetto React).

Da notare che nelle proprietà come larghezza, altezza o dimensione del carattere non è stata specificata l’unità di misura accanto al numero. Infatti, React Native utilizza di default i dp, pixel di densità, un concetto legato alla risoluzione dei dispositivi su cui l’app viene eseguita: 1 dp equivale a 1 pixel su schermi con densità standard, mentre schermi ad alta densità avranno più pixel nello stesso spazio, garantendo una maggiore chiarezza dell’immagine.

In conclusione, React Native si dimostra un mezzo flessibile ed efficace, permettendo ai programmatori di sviluppare applicazioni cross-platform sofisticate. Con una conoscenza dettagliata di componenti core e personalizzati, props, state e stili, si può trarre il massimo vantaggio da questa tecnologia per fornire esperienze mobile di elevato standard.

Vuoi saperne di più?

Contattaci

e scopri come possiamo aiutarti a riempire di innovazione il tuo progetto!