Expo è una raccolta di strumenti che semplificano la codifica delle app React Native. In questo tutorial, ti mostrerò come creare rapidamente app React Native usando Expo.
Con Expo, gli sviluppatori possono creare app React Native senza tutte le frustrazioni derivanti dall'installazione e configurazione di dipendenze software come Android Studio, Xcode o tutti gli altri strumenti necessari per sviluppare ed eseguire un'applicazione React Native.
In questo tutorial, ti mostrerò come creare un semplice gioco di memoria usando Expo. Lungo la strada imparerai anche quanto segue:
Expo è un framework per lo sviluppo rapido di app React Native. È come Laravel o Symphony per gli sviluppatori PHP o Ruby on Rails per gli sviluppatori di Ruby. Expo fornisce un livello in cima alle API React Native per renderle più facili da usare e gestire. Fornisce inoltre strumenti che semplificano il bootstrap e il test delle app React Native. Infine, fornisce componenti e servizi dell'interfaccia utente che sono comunemente disponibili solo quando si installa un componente React Native di terze parti. Tutti questi sono resi disponibili tramite l'SDK di Expo.
Prima di procedere ulteriormente, è importante essere consapevoli di alcuni dei limiti di Expo:
Anche con queste limitazioni, è importante tenere presente che Expo è una struttura completamente funzionale con un sacco di supporto per le API Android o iOS comunemente utilizzate. Ciò significa che ti ha coperto per la maggior parte delle funzionalità di cui le app di solito hanno bisogno. Quindi non c'è spesso bisogno di guardare fuori da Expo per implementare la funzionalità nativa.
L'app che stiamo per creare è un gioco di memoria. Potresti avere familiarità con questo tipo di gioco: l'utente deve trovare coppie corrispondenti girando le carte due alla volta. Ecco come appare la schermata predefinita:
Ed ecco come sembra che una volta aperte tutte le coppie:
Una volta risolto il gioco, l'utente può toccare reset pulsante per ripristinare gli elementi al loro stato iniziale. Questo permette loro di ricominciare tutto da capo.
A differenza del semplice React Native in cui devi installare e configurare Android Studio o Xcode e altre dipendenze, con Expo ci sono solo pochi passi da seguire per iniziare a sviluppare app:
npm install exp - global
Una volta installate tutte le dipendenze, ora puoi generare una nuova app Expo:
exp init MemoryGame
Una volta fatto, creerà una nuova cartella chiamata Gioco di memoria. Navigare all'interno e avviare l'esecuzione del server di sviluppo:
cd MemoryGame exp start
In alternativa, puoi anche usare Expo XDE. Ciò consente di creare ed eseguire app Expo tramite una GUI. Puoi scaricare l'installer dal repository Expo GitHub. Attualmente supporta solo Windows e Mac. Quindi se sei su Ubuntu o Linux è meglio restare con la linea di comando per ora.
Una volta che il server di sviluppo è in esecuzione, dovresti essere in grado di vedere qualcosa di simile a questo:
Questo è il codice QR che punta all'anteprima dal vivo del progetto. Apri l'app client di Expo sul tuo telefono e scansiona il codice usando lo scanner QR. A questo punto, dovresti essere in grado di visualizzare la schermata predefinita. Ogni volta che colpisci Control-S su uno qualsiasi dei file di progetto, l'anteprima dovrebbe ricaricarsi automaticamente per riflettere le modifiche.
Puoi trovare il codice sorgente completo del progetto sul suo repository GitHub. Oppure, se vuoi provare l'app, puoi dare un'occhiata alla demo. Basta selezionare il codice QR e scansionarlo sul telefono utilizzando l'app client di Expo.
Ora siamo pronti per codificare l'app. Iniziamo con alcuni componenti dell'interfaccia utente prima di tornare indietro e implementare il componente principale.
L'intestazione viene utilizzata per visualizzare il titolo dell'app. Creare un componenti cartella. Al suo interno, crea un Header.js file e aggiungere il seguente:
import Reagire da "reagire"; import StyleSheet, Text, View da 'react-native'; export default class Header estende React.Component render () return (); const styles = StyleSheet.create (header: flex: 1, flexDirection: 'column', alignSelf: 'stretch', paddingTop: 20, paddingBottom: 5, backgroundColor: '#f3f3f3', header_text: fontWeight: 'bold', fontSize: 17, textAlign: 'center'); Gioco di memoria
Questo è solo un componente React Native di base, con uno stile che si abbina all'interfaccia utente della nostra app.
Il prossimo è il componente per la visualizzazione del punteggio (componenti / Score.js):
import Reagire da "reagire"; import StyleSheet, Text, View da 'react-native'; Esporta la classe di default Punteggio estende React.Component render () return (); const styles = StyleSheet.create (score_container: flex: 1, alignItems: 'center', padding: 10, score: fontSize: 40, fontWeight: 'bold'); This.props.score
Ancora una volta, solo un semplice componente di visualizzazione con una visualizzazione di testo e alcuni stili di base.
Il componente della carta (componenti / Card.js) mostrerà le carte. Queste carte usano icone del set di icone vettoriali di Expo. Questa è una delle caratteristiche che escono subito dalla scatola quando usi Expo: include icone di set di icone come FontAwesome, Entypo e Ionicons.
Nel codice qui sotto, puoi vedere che stiamo usando FontAwesome. Ha l'icona che vogliamo per visualizzare lo stato di default della carta: un punto interrogativo. Come vedremo più avanti nel componente principale dell'app, useremo anche le icone di Entypo e Ionicons. Il riferimento a tali sorgenti di icone verrà passato a questo componente, quindi non è necessario specificarli qui:
import Reagire da "reagire"; import StyleSheet, Text, View, TouchableHighlight da 'react-native'; importare FontAwesome da "@ expo / vector-icons"; // usa FontAwesome dalle icone vettoriali expo
Dentro il render ()
metodo, usiamo solo la fonte e l'icona passata come oggetti di scena se la carta è aperta. Per impostazione predefinita, verrà visualizzata l'icona del punto interrogativo solo da FontAwesome. Ma se la carta è aperta, utilizzerà la fonte dell'icona, l'icona e il colore che sono stati passati come oggetti di scena.
È possibile toccare ciascuna delle carte. Quando toccato, il clickCard ()
verrà eseguita la funzione, che viene anche passata attraverso i puntelli. Più avanti vedrai cosa fa la funzione, ma per ora, sappi solo che aggiorna lo stato per rivelare l'icona sulla carta:
export default class Card estende React.Component render () let CardSource = FontAwesome; // imposta FontAwesome come l'icona predefinita source let icon_name = 'question-circle'; let icon_color = '# 393939'; if (this.props.is_open) CardSource = this.props.src; icon_name = this.props.name; icon_color = this.props.color; ritorno ();
Non dimenticare di aggiungere gli stili:
const styles = StyleSheet.create (card: flex: 1, alignItems: 'center', card_text: fontSize: 50, fontWeight: 'bold');
Useremo anche una funzione di aiuto chiamata Shuffle ()
. Questo ci permette di ordinare la matrice di carte in ordine casuale in modo che il loro ordine sia diverso ogni volta che il gioco viene ripristinato:
Array.prototype.shuffle = function () var i = this.length, j, temp; se (i == 0) restituisce questo; while (- i) j = Math.floor (Math.random () * (i + 1)); temp = this [i]; questo [i] = questo [j]; questo [j] = temp; restituisci questo;
Il componente principale (App.js) contiene la logica dell'app principale e riunisce tutto. Inizia includendo i pacchetti React ed Expo che utilizzeremo. Questa volta utilizzeremo tutte le risorse delle icone dalle icone vettoriali di Expo:
import Reagire da "reagire"; import StyleSheet, View, Button da 'react-native'; importare Ionicons, FontAwesome, Entypo da "@ expo / vector-icons";
Successivamente, includi i componenti e l'helper che abbiamo creato in precedenza:
importare l'intestazione da "./components/Header"; punteggio di importazione da './components/Score'; scheda di importazione da './components/Card'; importare helper da './helpers';
All'interno del costruttore, per prima cosa creiamo l'array che rappresenta le carte uniche. src
è la fonte dell'icona, nome
è il nome dell'icona (puoi trovare i nomi su GitHub se vuoi usare altre icone), e colore
è, naturalmente, il colore dell'icona:
esportazione di classe predefinita App estende React.Component costruttore (oggetti di scena) super (oggetti di scena); // associa le funzioni alla classe this.renderCards = this.renderCards.bind (this); this.resetCards = this.resetCards.bind (this); // icon sources consente a sources = 'fontawesome': FontAwesome, 'entypo': Entypo, 'ionicons': Ionicons; // le icone uniche da usare let cards = [src: 'fontawesome', nome: 'heart', colore: 'red', src: 'entypo', nome: 'feather', color: '# 7d4b12 ', src:' entypo ', nome:' flashlight ', colore:' # f7911f ', src:' entypo ', nome:' flower ', colore:' # 37b24d ', src:' entypo ', nome:' moon ', colore:' # ffd43b ', src:' entypo ', nome:' youtube ', colore:' # FF0000 ', src:' entypo ', nome:' shop ', color: '# 5f5f5f', src: 'fontawesome', nome: 'github', colore: '# 24292e', src: 'fontawesome', nome: 'skype', colore: '# 1686D9', src: 'fontawesome', nome: 'send', colore: '# 1c7cd6', src: 'ionicons', nome: 'ios-magnete', colore: '# d61c1c', src: 'ionicons' , nome: 'logo-facebook', colore: '# 3C5B9B']; // next: aggiungi il codice creando il clone e impostando le carte nello stato
Si noti che invece di specificare direttamente il src
come FontAwesome
, Entypo
o Ionicons
per ciascuno degli oggetti, stiamo usando i nomi delle proprietà usati nel fonti
oggetto. Questo perché avremo bisogno di creare una copia della serie di carte in modo che ogni carta abbia una coppia. Creare una copia usando metodi array come fetta()
creerà una copia dell'array, ma il problema è che una volta modificati i singoli oggetti sia nella copia che nell'originale, entrambi gli array vengono modificati.
Questo ci porta alla soluzione qui sotto che è creare un oggetto completamente nuovo convertendo il carte
array in una stringa e quindi analizzarlo per convertirlo in un array. Questo è il motivo per cui utilizziamo le stringhe poiché le funzioni non possono essere convertite in stringhe. Combiniamo quindi i due per creare l'array, che contiene tutte le carte di cui abbiamo bisogno:
let clone = JSON.parse (JSON.stringify (cards)); // crea una matrice completamente nuova dalla matrice di carte this.cards = cards.concat (clone); // combina l'originale e il clone
Quindi, passa attraverso quell'array e genera un ID univoco per ognuno, imposta l'origine dell'icona e quindi imposta lo stato chiuso per impostazione predefinita:
// aggiungi l'ID, l'origine e lo stato di default di ogni scheda this.cards.map ((obj) => let id = Math.random (). toString (36) .substring (7); obj.id = id ; obj.src = sources [obj.src]; obj.is_open = false;);
Ordina le carte a caso e imposta lo stato di default:
this.cards = this.cards.shuffle (); // ordina le carte a caso // imposta lo stato predefinito this.state = current_selection: [], // questa matrice conterrà una matrice di oggetti di carta che sono attualmente selezionati dall'utente. Questo conterrà solo due oggetti alla volta. selected_pairs: [], // i nomi delle icone. Questo array viene usato per escluderli da ulteriori punteggi di selezione: 0, // carte punteggio utente predefinite: this.cards // le carte mescolate
Il render ()
metodo restituisce l'intestazione, le carte, il punteggio e il pulsante per reimpostare il gioco corrente. Sta usando il renderRows ()
funzione per rendere le singole righe di carte. Lo schermo avrà sei righe contenenti quattro carte ciascuna:
render () return (); this.renderRows.call (this)
Ecco il codice per il renderRows ()
funzione. Questo usa il getRowContents ()
funzione, che è responsabile della creazione di una matrice di matrici con quattro voci ciascuna. Questo ci permette di rendere ogni riga, e quindi usare un'altra funzione per rendere le carte per ogni iterazione del carta geografica()
funzione:
renderRows () let contents = this.getRowContents (this.state.cards); return contents.map ((cards, index) => return (this.renderCards (cards) ); );
Ecco il getRowContents ()
funzione:
getRowContents (cards) let contents_r = []; let contents = []; let count = 0; cards.forEach ((item) => count + = 1; contents.push (item); if (count == 4) contents_r.push (contents) count = 0; contents = [];); return contents_r;
Il prossimo è il renderCards ()
funzione. Questo accetta la matrice di oggetti di carte e li rende tramite il Carta
componente. Tutto ciò che dobbiamo fare qui è passare le singole proprietà di ogni oggetto di carta come oggetti di scena. Questo viene quindi utilizzato per rendere l'icona corretta, come hai visto nel codice per il Carta
componente. Il clickCard ()
la funzione è anche passata come sostegno. L'ID della carta viene passato a quella funzione in modo che la carta unica possa essere identificata e aggiornata:
renderCards (cards) return cards.map ((card, index) => return (); );
Dentro il clickCard ()
funzione, otteniamo i dettagli della carta selezionata e controlliamo se deve essere elaborata ulteriormente:
clickCard (id) let selected_pairs = this.state.selected_pairs; let current_selection = this.state.current_selection; let score = this.state.score; // ottiene l'indice della scheda attualmente selezionata let index = this.state.cards.findIndex ((card) => return card.id == id;); let cards = this.state.cards; // la carta non dovrebbe essere già aperta e non si trova sull'array di carte le cui coppie sono già selezionate se (cards [indice] .is_open == false && selected_pairs.indexOf (cards [index] .name) === - 1) // next: aggiungi codice per l'elaborazione della carta selezionata
Ora inseriamo il codice per la gestione di una carta selezionata.
Per prima cosa, apriamo la carta e la aggiungiamo alla matrice delle carte attualmente selezionate:
cards [indice] .is_open = true; current_selection.push (index: index, name: cards [index] .name); // next: aggiungi il codice per determinare se l'utente ha selezionato o meno la coppia corretta
Una volta che ci sono due elementi nella matrice delle carte attualmente selezionate, controlliamo se i nomi delle icone sono gli stessi. Se lo sono, significa che l'utente ha selezionato la coppia corretta. Se non sono uguali, allora è una coppia sbagliata. In tal caso, chiudiamo la prima carta selezionata e aggiungiamo un po 'di ritardo prima di chiudere la seconda carta. (In questo modo l'utente può vedere l'icona della scheda prima che ritorni allo stato chiuso.)
if (current_selection.length == 2) if (current_selection [0] .name == current_selection [1] .name) score + = 1; // incrementa il punteggio selected_pairs.push (cards [index] .name); else cards [current_selection [0] .index] .is_open = false; // chiudi il primo // ritardo che chiude la carta attualmente selezionata di mezzo secondo. setTimeout (() => cards [indice] .is_open = false; this.setState (cards: cards);, 500); current_selection = []; // next: aggiungi il codice per l'aggiornamento dello stato
L'ultima cosa che dobbiamo fare nel gestore di eventi click è aggiornare lo stato per riflettere le modifiche nell'interfaccia utente:
this.setState (score: score, cards: cards, current_selection: current_selection);
Una funzione correlata è il gestore di eventi di reset. Quando il reset toccato, ripristiniamo semplicemente lo stato di default chiudendo tutte le carte e mescolando.
resetCards () // chiudi tutte le carte let cards = this.cards.map ((obj) => obj.is_open = false; return obj;); cards = cards.shuffle (); // re-shuffle le carte // aggiorna allo stato predefinito this.setState (current_selection: [], selected_pairs: [], cards: cards, score: 0);
Infine, aggiungeremo alcuni stili di base per rendere la nostra app un bell'aspetto.
const styles = StyleSheet.create (container: flex: 1, alignSelf: 'stretch', backgroundColor: '#fff', row: flex: 1, flexDirection: 'row', body: flex: 18, justifyContent: 'spazio-tra', padding: 10, marginTop: 20);
Dal momento che il tuo server di sviluppo di Expo è in esecuzione da un po 'di tempo, ogni modifica deve essere trasferita sul tuo dispositivo mobile con il caricamento in tempo reale. Prova l'app e assicurati che funzioni come dovrebbe.
Questo è tutto! In questo tutorial hai imparato come utilizzare Expo XDE per collegare rapidamente un'app React Native. Expo è un ottimo modo per iniziare a sviluppare app React Native perché elimina la necessità di installare un sacco di software che è spesso causa di frustrazione, soprattutto per i principianti. Fornisce inoltre strumenti che facilitano notevolmente l'anteprima dell'app durante lo sviluppo. Assicurati di controllare le risorse menzionate sul sito di Expo se vuoi saperne di più.
E nel frattempo, dai uno sguardo ad alcuni dei nostri altri post sullo sviluppo di app React Native!