Categories
boilerplate solution linguaggio javascript moduli Node.js React Native

React Native template (1)

Analizziamo la struttura del progetto3 (applicazione dimostrativa creata nei precedenti post12 ).

Il progetto è stato ottenuto (dalla rete Internet) con questo comando:

  • La scelta del nome è permanente (molto difficile da cambiare)
  • Prima di scegliere il nome del progetto è buona regola controllare se nel web esiste già una App con lo stesso nome nei repository Android e iOS.
$ nvm use node
$ npx react-native init progetto3

Nel febbraio 2023 le sue dimensioni si aggirano intorno ai 340 MB.

Analizzando la struttura delle cartelle si può osservare approssimativamente questa struttura:

.
+ ── android
+ ── ios
+ ── node_modules
├─── App.js
├─── index.js
└─── package.json

Cosa contegono questi file e queste cartelle create dal nulla?

Chi lo desidera, può creare manualmente questa struttura, ma la forma della struttura dei progetti è sempre simile a questa. Per tale motivo, in termini tecnici, può essere chiamata “template“, oppure “boilerplate solution“, nel senso che tale soluzione si ripete spesso come un piatto pronto (il termine boilerplate deriva dalla consuetudine nelle tecniche di stampa).

In futuro vedremo altre soluzioni, altri template, altre boilerplate solution, ma per ora, vediamo alcune caratteristiche di questo semplice esempio:

  • Le prime due cartelle (android e ios) non devono essere modificate direttamente (a parte casi particolari), ma contengono il codice generato automaticamente in fase di transcompilazione per le due piattaforme Android e iOS.
  • La terza cartella node_modules contiene i moduli, le librerie, Node.js installati localmente con npm
  • package.json contiene informazioni descrittive del progetto, metadati: nome, versione SDK, ecc.
    • ad esempio, questo codice:
      "type": "module"
      indica come il tipo di moduli da utilizzare nel progetto (ad esempio, per importare librerie)
  • index.js è solo il punto di ingresso (entry point) dell’applicazione, e se si escludono gli import, esso è composto in sostanza da una riga (la riga 5):
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

Vale la pena soffermarsi sulla sintassi dell’ultima riga, dove è presente una arrow function. Le arrow function sono semplici funzioni in JavaScript. Possono essere anonime e possono essere definite “in linea” nel posto dove devono essere usate. In questo caso sono passate come parametro ad altre funzioni.

App.js è il vero e proprio codice sorgente, vediamo le parti salienti (la numerazione delle righe potrebbe non corrispondere):

const App = () => {
  return (
    <SafeAreaView>
      <StatusBar>
        <ScrollView>
          <Header/>
          <View>
            <Section title="primo tentativo">
              Questa è una prova
            </Section>
          </View>
        </ScrollView>
      </StatusBar>
    </SafeAreaView>
  );
};

export default App;
  • App è una funzione (arrow function, ma potrebbe essere anche una classe)
  • l’ultima riga esporta la funzione App per poterla usare dentro index.js (già visto)
  • App restituisce un elemento che poi verrà rappresentato dentro l’applicazione dello smartphone
    • questi elementi assomigliano a tag con iniziale Maiuscola. In effetti non sono tag HTML ma sono istanze di componenti (classi) di React
  • La parte di rendering utilizza (per semplicità) il linguaggio JSX (tag maiusoli e altro)
  • La parte di rendering è all’interno di return
  • La parte di rendering deve avere le parentesi tonde nel caso in cui sia necessario usare più di una sola riga
  • JSX ha anche altre regole che saranno approfondite con altri esempi
  • I vari componenti sono organizzati in un albero gerarchico
  • I componenti senza figli si devono autochiudere (come Header)
  • I vari componenti possono avere attributi (come i tag in HTML)
  • Il component Section è un figlio sconosciuto e viene definito in un’altra parte del codice sorgente (di solito il suo codice è salvato in un diverso file sorgente di nome Section.js)
  • Tutti gli altri component genitori si possono ottenere da React Native con import

Vediamo la parte che riguarda il component Section (la numerazione delle righe potrebbe non corrispondere):

const Section = ({children, title}) => {
  return (
    <View>
      <Text> {title} </Text>
      <Text> {children} </Text>
    </View>
  );
};
  • Anche Section è un component definito come funzione dal programmatore (arrow function), ma poteva essere definito anche come classe
  • esso restituisce un elemento che verrà poi rappresentato dentro l’applicazione (rendered element)
  • nella riga 1 “title” e “children” sono proprietà (props) che sono ricevute da Section e che vengono forniti dall’elemento genitore (App)
  • nella riga 4 una proprietà stringa viene visualizzata grazie alle parentesi graffe {}. In linguaggio JSX, infatti, si possono racchiudere le stringhe in JavaScript dentro le semplici parentesi graffe {}.
  • la proprietà “title” è una semplice stringa, facile da capire, facile da passare (da App a Section)
  • la proprietà “children” viene passata in modo diverso. Permette di passare tutto il contenuto racchiuso da un component (un testo o un ulteriore component). Vedere il codice di App alla riga 9.
  • In questo caso il programmatore ha deciso di passare la proprietà “Questa è una prova” in modo diverso dalla proprietà “title“, anche se non era necessario cambiare metodo. È stata solo una scelta dimostrativa.
  • A dire la verità questo cambiamento potrebbe complicare la comprensione dell’esempio.
  1. https://www.cancellino.org/2023/01/react-native-con-android-1/ []
  2. https://www.cancellino.org/2023/01/react-native-con-android-3/ []

Leave a Reply