Le but de ce tutoriel est de vous guider dans les premières étapes avec React Native.
Créons une application à l'aide de l'API TV Maze et en suivant le prototype ci-dessous:

Ce tutoriel est en construction. Jusqu'à présent, il couvre les points suivants:
Référentiel avec le code prêt, également en construction : https://github.com/erbuen/favtvshow :)
Avant de commencer à écrire du code, il est important de comprendre les comportements associés à chaque écran.
C'est l'écran que l'utilisateur affichera lors du démarrage de l'application.

Elle devrait avoir une barre de recherche et, sur le côté droit de la barre, un bouton.
La barre de recherche doit avoir un espace réservé. Lorsque vous entreprenez un mot à rechercher, nous devons utiliser le bouton que le clavier met à la disposition de la recherche, par exemple, comment nous nous produisons lorsque nous tapons une URL dans le navigateur mobile.
La recherche de résultats doit être affichée sous la barre de recherche et sous le titre "Résultat de la recherche", une par ligne. Si vous n'obtenez aucun résultat, vous devez afficher le message "Aucun résultat trouvé".
Les résultats doivent être affichés sous forme de «cartes» contenant l'image, le nom de la série et les genres qui y sont attribués (voir section 1.3).
Lorsque l'utilisateur sélectionne l'un des résultats, il doit être transporté sur un autre écran qui affichera les informations complètes de la série. Nous décrirons cet écran bientôt.
Le bouton droit de la barre de recherche, lorsqu'il est cliqué, devrait afficher la série préférée de l'utilisateur sous le titre "Favoris".
S'il n'y a pas de recherche en cours, n'affichez rien à l'écran.
S'il n'y a pas de série préférée, affichez le message "Vous n'avez toujours pas de série préférée".
Lorsque l'utilisateur clique sur une série, soit dans les résultats de la recherche, soit en faveur, il doit être transporté sur cet écran.

Cet écran doit afficher une image associée à la série, au nom, aux genres et au résumé.
À côté du nom et des genres, vous devriez avoir un bouton pour que l'utilisateur puisse favoriser la série.
Lorsque l'utilisateur clique sur le bouton pour favoriser la série, les données doivent être enregistrées dans le stockage global interne de l'application et il devrait y avoir un retour visuel à l'utilisateur qui pourrait être un "toast" ou similaire.
Au-dessus de l'image de la série, vous devriez avoir un bouton de retour qui passera à l'écran précédent.
L'utilisateur doit pouvoir rouler l'écran car le contenu du résumé peut être supérieur à la taille de l'écran de l'appareil.
Vous verrez une liste de séries lorsque vous recherchez et obtenez au moins un résultat ou lorsque vous accédez à votre série préférée.
À cette fin, nous devons construire un composant de carte comme image ci-dessous:

Les cartes doivent être cliquées et affichées sur une liste plate.
Le moment est venu de démarrer le projet! Pour ce faire, visitez la page React Native et cliquez sur Démarrer .

Sur la page de démarrage , vous trouverez toutes les informations dont vous avez besoin pour commencer par React Native. Pour ce tutoriel, nous vous suggérons de choisir l'option React Native ClickStart .

Choisissez ensuite la meilleure option qui correspond à votre profil. Dans mon cas, je me développerai à l'aide d'un Mac, donc en développement, je les ai choisis et comme je vais tester à l'aide de l'iPhone, dans Target , j'ai choisi la cible comme iOS , mais j'aurais pu choisir Android .

Vous ne pouvez choisir Target que comme iOS si vous utilisez un Mac. Pour Windows et Linux , vous devez nécessairement choisir Android .
Après avoir sélectionné les options en fonction de votre système d'exploitation, suivez les instructions pour l'installation des installations nécessaires pour utiliser React Native.
Après avoir terminé l'installation de toutes les dépendances en fonction de l'étape par étape du site natif React, vous pourrez démarrer votre projet avec la commande suivante:
npx react-native init NomeDoProjetoLa création du projet peut prendre quelques minutes, ne vous inquiétez pas et suivez les journaux via le terminal :)
Une fois le processus terminé, vous pouvez exécuter votre projet avec les commandes suivantes:
cd NomeDoProjeto
npx react-native run-iosSi vous utilisez macOS. Ou, si vous utilisez Windows ou Linux:
cd NomeDoProjeto
npx react-native run-androidAprès un certain temps - et la première fois que nous exécutons cette commande peut vraiment prendre beaucoup de temps - vous verrez quelque chose comme ça (selon le système d'exploitation cible ):

IMPORTANT: Notez que le texte du projet par défaut dans la première exécution (pas de modifications) mentionne les options pour que vous visiez vos modifications (rechargement) et également pour déboguer. Cela signifie que vous pouvez modifier le code et voir les modifications et effectuer le débogage en temps réel.
Pour que vous modifiez le projet, vous devez utiliser un éditeur de code de votre choix:
Lors de l'ouverture du projet dans l'éditeur de code de votre choix, vous verrez cette structure de dossier et de fichier:

Remarque: Ceci est la barre latérale de mon code Visual Studio. J'utilise un thème différent de la norme et j'ai également une extension qui modifie les images des icônes associées à chaque fichier ou dossier. Le nom que j'ai donné à mon projet est FavtvShow .
Ce qui est important à savoir ici:
Les dossiers Android et iOS contiennent le code natif généré. Vous pouvez exécuter votre application sur Android Studio ou Xcode ouvrant respectivement ces dossiers dans chaque IDE. Ces dossiers sont importants pour générer la libération de votre application.
Le dossier Node_Modules contient toutes les installations du projet installées par le NPM.
L'application peut être initialement modifiée via le fichier app.js.
Le fichier index.js cherche et enregistre le composant global de notre application, c'est-à-dire le premier composant à charger. Il importe le contenu du fichier APP.js et rendu à l'écran.
Le fichier package.json contient toutes les données sur les lieux et également des scripts liés à votre projet.
Supprimez tous les contenus du fichier app.js et remplacez-le par:
import React , { Component } from 'react' ; // 1
import { Text , View , StyleSheet } from 'react-native' ; // 2
// 3
export default class App extends Component {
render ( ) {
return (
// 4
< View style = { styles . hello } >
< Text > Hello, world! </ Text >
</ View >
) ;
}
}
// 5
const styles = StyleSheet . create ( {
hello : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
} ) ;Lorsque vous supprimez le contenu app.js, mettez ce nouveau contenu et enregistrez le fichier, si vous avez le simulateur en cours d'exécution, il recharge automatiquement la vue.
Assurez-vous de lire la documentation officielle sur le texte et les composants de la vue et la feuille de style d'abstraction.
Changeons un peu le style du texte dans le composant de texte . Tout d'abord, réécrivez la ligne de ligne de texte pour que ce soit comme ceci:
< Text style = {styles.text} > Hello, world! </ Text >Ajoutez ensuite le style de texte dans les styles . Ce sera comme ceci:
const styles = StyleSheet . create ( {
hello : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
text : {
fontSize : 30 ,
color : 'blue' ,
} ,
} ) ;Voir le résultat dans le simulateur lorsque vous enregistrez le fichier! :)
Nous devons commencer à donner un visage à notre projet selon le prototype. Nous le ferons aussi simplement que possible, au moins au début.
Comment pouvons-nous ajouter les éléments nécessaires de l'écran d'accueil? L'un d'eux est une barre de recherche. Il y a des bibliothèques avec ce composant prêt, mais afin que nous puissions apprendre à le faire, nous ne les utiliserons pas.
Ajoutons le composant TextInput à notre deuxième ligne d' importation . Voir la documentation de ce composant ici.
import { Text , View , StyleSheet , TextInput } from 'react-native' ;Modifions le passage de code qui s'occupe de rendre l'écran comme ceci:
export default class App extends Component {
render ( ) {
return (
< View style = { styles . screen } >
< View style = { styles . search } >
< TextInput style = { styles . input } />
</ View >
< View style = { styles . results } >
< Text > Os resultados aparecerão aqui </ Text >
</ View >
</ View >
) ;
}
}Nous avons un composant de vue qui résume tous les éléments de l'écran et il reçoit le style d'écran .
Dans ce composant, nous avons deux autres composants de vue : un en haut (fond blanc) qui reçoit le style de recherche et un ci-dessous (gris clair temporairement pour la visualisation) qui reçoit les résultats .
Dans le composant supérieur, nous avons le composant TextView . Et à l'intérieur du composant en bas de l'écran, nous avons le composant texte .
Modifions maintenant les styles afin qu'ils soient ainsi:
const styles = StyleSheet . create ( {
screen : {
flex : 1 ,
flexDirection : 'column' ,
} ,
search : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
input : {
marginTop : 55 ,
height : 40 ,
width : 250 ,
borderColor : 'lightgray' ,
borderWidth : 1 ,
padding : 10 ,
fontSize : 20 ,
} ,
results : {
flex : 4 ,
backgroundColor : 'lightgray' ,
alignItems : 'center' ,
} ,
} ) ;Apporter les modifications et enregistrer le fichier. Voir maintenant l'explication de chaque élément:
Le composant de vue qui englobe tous les autres composants (style de nom d' écran ) a un flexion égal à 1. Cela en fait tout écran, car il englobe tous les autres. Il a unedirection flexible égale à la colonne car nous voulons que les composants à l'intérieur s'organisent verticalement.
Nous avons le composant de style Search - Style vers le haut et les résultats avec des résultats qui restent ci-dessous. Ils sont à l'intérieur du composant View avec le style d'écran et s'organisent verticalement. Ils doivent diviser le même espace. Nous le faisons en utilisant le flex. La tige a Flex 1 et les 4 inférieurs. IMPORTANT: Voir React Native Documentation pour en savoir plus sur Flexbox :)
En regardant le composant de vue de style de recherche , à l'intérieur, nous mettons le composant TextView qui est personnalisé avec le style d'entrée . Avec lui, nous avons pu définir sa hauteur (hauteur), sa largeur (largeur), la distance de la marge supérieure de l'écran (margintop), la couleur de la frontière, l'épaisseur de la largeur de bordure, la taille de la source en arrière (rembourrage) et la taille de la source de champ (Fontize).
Dans le simulateur, si vous cliquez sur TextInput , le clavier apparaît automatiquement. Vous pouvez taper quelque chose et cliquer sur "retour" (dans le cas d'iOS). Pour l'instant, rien ne se passera car nous devons encore mettre en œuvre le comportement.
Ajoutons une variable appelée état avant la fonction render () qui recevra le texte tapé dans le TextInput .
state = {
searchText : '' ,
}Nous changerons également TextInput pour avoir un espace réservé et pour le sauvegarder dans la variable d'état le texte typé. Il sera comme ceci:
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
/>Remarquez la méthode OnChangeText du composant. Il reçoit la valeur du texte et enregistré (this.setState) dans SearchText . Nous pouvons vérifier cela en temps réel en faisant un petit changement dans un autre composant.
Où nous avons:
< Text > Os resultados aparecerão aqui </ Text >Changer pour:
< Text > {this.state.searchText} </ Text >Enregistrer et tester pour taper quelque chose dans TextInput :)
Changer un peu plus notre TextInput , utilisons la méthode onSubmitediting pour que la recherche se produise lorsque l'utilisateur appuie sur la touche de retour (ou équivalent sur Android). Pour l'instant, nous ne ferons aucune demande à l'API, mais nous laisserons les choses transmises!
Notre TextInput sera comme ceci:
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
onSubmitEditing = { ( ) => this . submitSearch ( ) }
/>Nous devons ajouter la fonction SubmitSearch () , cela peut être fait juste en dessous de l'état . Ce sera comme ceci:
state = {
searchText : '' ,
}
submitSearch ( ) {
alert ( 'Buscar: ' + this . state . searchText ) ;
}Comme nous ne faisons pas encore la demande, j'ai mis une alerte afin que vous réalisiez que le contenu tapé dans le champ de texte sera utilisé dans la recherche, car il se produira dans la fonction SubmitSearch () .
Pour que nous puissions populser notre application avec des données, utilisons le labyrinthe API TV qui est une API de repos ouverte (nous n'avons pas besoin d'authentification), gratuitement et renvoie les données au format JSON.
Regardons un exemple de recherche en utilisant cette API. Si nous voulons effectuer une recherche avec le mot anatomie , nous utiliserons le point de terminaison suivant:
[GET] http://api.tvmaze.com/search/shows?q=anatomy
En conséquence, nous aurons le JSON ci-dessous (un seul tronçon est montré) contenant toutes les entrées qui ont de l'anatomie ou quelque chose comme:
[
{
"score" : 20.919525 ,
"show" : {
"id" : 67 ,
"url" : " http://www.tvmaze.com/shows/67/greys-anatomy " ,
"name" : " Grey's Anatomy " ,
"type" : " Scripted " ,
"language" : " English " ,
"genres" : [
" Drama " ,
" Romance " ,
" Medical "
],
"status" : " Running " ,
"runtime" : 60 ,
"premiered" : " 2005-03-27 " ,
"officialSite" : " http://abc.go.com/shows/greys-anatomy/ " ,
"schedule" : {
"time" : " 21:00 " ,
"days" : [
" Thursday "
]
},
"rating" : {
"average" : 8.3
},
"weight" : 99 ,
"network" : {
"id" : 3 ,
"name" : " ABC " ,
"country" : {
"name" : " United States " ,
"code" : " US " ,
"timezone" : " America/New_York "
}
},
"webChannel" : null ,
"externals" : {
"tvrage" : 3741 ,
"thetvdb" : 73762 ,
"imdb" : " tt0413573 "
},
"image" : {
"medium" : " http://static.tvmaze.com/uploads/images/medium_portrait/211/529884.jpg " ,
"original" : " http://static.tvmaze.com/uploads/images/original_untouched/211/529884.jpg "
},
"summary" : " <p>The doctors of Grey Sloan Memorial Hospital deal with life-or-death consequences on a daily basis -- it's in one another that they find comfort, friendship and, at times, more than friendship. Together they're discovering that neither medicine nor relationships can be defined in black and white. Real life only comes in shades of grey.</p> " ,
"updated" : 1576320037 ,
"_links" : {
"self" : {
"href" : " http://api.tvmaze.com/shows/67 "
},
"previousepisode" : {
"href" : " http://api.tvmaze.com/episodes/1749376 "
},
"nextepisode" : {
"href" : " http://api.tvmaze.com/episodes/1760391 "
}
}
}
},
{
"score" : 15.932307 ,
"show" : {
"id" : 34388 ,
"url" : " http://www.tvmaze.com/shows/34388/greys-anatomy-b-team " ,
"name" : " Grey's Anatomy: B-Team " ,
"type" : " Scripted " ,
"language" : " English " ,
"genres" : [
" Drama " ,
" Romance " ,
" Medical "
],
"status" : " Ended " ,
"runtime" : 3 ,
"premiered" : " 2018-01-11 " ,
"officialSite" : " http://abc.go.com/shows/greys-anatomy-b-team " ,
"schedule" : {
"time" : " " ,
"days" : [
" Thursday "
]
},
"rating" : {
"average" : null
},
"weight" : 80 ,
"network" : null ,
"webChannel" : {
"id" : 95 ,
"name" : " ABC.com " ,
"country" : {
"name" : " United States " ,
"code" : " US " ,
"timezone" : " America/New_York "
}
},
"externals" : {
"tvrage" : null ,
"thetvdb" : null ,
"imdb" : null
},
"image" : {
"medium" : " http://static.tvmaze.com/uploads/images/medium_portrait/142/355662.jpg " ,
"original" : " http://static.tvmaze.com/uploads/images/original_untouched/142/355662.jpg "
},
"summary" : " <p>A fresh crop of interns face their first day at Grey Sloan Memorial Hospital. Can these new surgeons survive the pressures of high-stakes medicine, intimidating attendings, and cut throat competition?</p> " ,
"updated" : 1526845476 ,
"_links" : {
"self" : {
"href" : " http://api.tvmaze.com/shows/34388 "
},
"previousepisode" : {
"href" : " http://api.tvmaze.com/episodes/1390266 "
}
}
}
}
]Vous pouvez voir une version plus conviviale du contenu de ce JSON à l'aide de JSON Editor Online. Je suis laissé enregistré pour que vous puissiez tout voir! Cliquez ici ;)
Dans JSON Editor Online, il était facile de voir qu'il s'agit d'un tableau avec 9 objets et que chaque objet est une série.
Selon le prototype et ce que nous avons mis en œuvre jusqu'à présent:
Mettons cela en pratique dans la section suivante en utilisant Axios.
Nous devons installer la bibliothèque Axios dans le projet. Nous le ferons en tapant la commande suivante au terminal:
$ npm install axiosAprès cela, créons un dossier de service et un fichier api.js à l'intérieur. Mettez le code suivant dans le fichier:
import axios from 'axios' ; // 1
// 2
const api = axios . create ( {
baseURL : 'http://api.tvmaze.com/' ,
} ) ;
export default api ;Dans app.js , importons le fichier api.js :
import api from './service/api' ;Et modifions la fonction de recherche SubmitSearch pour être comme ceci:
submitSearch = async ( ) => { // 1
if ( this . state . searchText != '' ) { // 2
try { // 3
const response = await api . get ( '/search/shows' , { // 4
params : { q : this . state . searchText } // 5
} ) ;
alert ( JSON . stringify ( response ) ) ;
} catch ( error ) {
alert ( JSON . stringify ( error ) ) ;
}
}
}Les alertes à l'intérieur du bloc d'essai et dans le bloc de capture seront utiles pour visualiser les réponses obtenues dans la demande. À un autre moment, nous utiliserons ces réponses d'une autre manière :)
En savoir plus sur les fonctions asynchrones ici et sur les promesses ici.
Commençons à implémenter FlatList pour afficher la liste des résultats de recherche. Modifions notre importation pour ceci:
import { Text , View , StyleSheet , TextInput , FlatList } from 'react-native' ;Ensuite, nous modifierons l' état et la fonction subitsearch () afin qu'ils soient:
state = {
searchText : '' ,
searchResults : null , // 1
}
submitSearch = async ( ) => {
if ( this . state . searchText != '' ) {
try {
const response = await api . get ( '/search/shows' , {
params : { q : this . state . searchText } ,
} ) ;
this . setState ( { searchResults : response . data } ) ; // 2
} catch ( error ) {
alert ( JSON . stringify ( error ) ) ;
}
}
}Nous devons également modifier le rendu () , en insérant la liste plate :
render ( ) {
return (
< View style = { styles . screen } >
< View style = { styles . search } >
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
onSubmitEditing = { ( ) => this . submitSearch ( ) }
/>
</ View >
< View style = { styles . results } >
< FlatList
data = { this . state . searchResults }
renderItem = { ( { item } ) => < Text > { item . show . name } </ Text > }
keyExtractor = { item => item . show . id }
/>
</ View >
</ View >
) ;
}Notez que nous ne rendons que le nom de la série avec le composant texte . Cependant, créons notre type de carte ici, selon la section 1.3.
Dans un projet, nous créerons peut-être plus d'un composant. Pour faciliter l'organisation, créons un dossier composant et tous les composants que nous créons seront enregistrés.
Dans ce dossier, nous créerons un fichier appelé card.js avec le contenu suivant:
import React , { Component } from 'react' ;
import { Text , View , TouchableOpacity , Image , StyleSheet } from 'react-native' ;
export default class Card extends Component {
render ( ) {
return (
< TouchableOpacity style = { styles . container } >
< View style = { styles . cardView } >
< View >
< Image
style = { styles . image }
source = { { uri : this . props . info . image == null ? 'https://i.ibb.co/YfZFr7k/noimg.png' : ( this . props . info . image . original || this . props . info . image . medium ) } }
/>
</ View >
< View style = { { flexDirection : 'column' } } >
< Text style = { styles . name } > { this . props . info . name || 'Sem nome' } </ Text >
< Text style = { styles . genres } > { this . props . info . genres || 'Sem gênero' } </ Text >
</ View >
</ View >
</ TouchableOpacity >
) ;
}
}
const styles = StyleSheet . create ( {
container : {
padding : 10 ,
} ,
cardView : {
alignItems : 'center' ,
flexDirection : 'row' ,
} ,
image : {
width : 80 ,
height : 120 ,
resizeMode : 'contain' ,
} ,
name : {
fontSize : 20 ,
marginLeft : 10 ,
} ,
genres : {
fontSize : 16 ,
marginLeft : 10 ,
} ,
} ) ;Notez que le nom du composant est la carte et que j'ai utilisé une image pour servir d'espace réservé si la série n'a pas d'URL valide.
Importons maintenant notre nouveau composant dans le fichier app.js :
import Card from './components/card' ;Et dans Flatlist, nous remplacerons le contenu actuel par:
< FlatList
data = { this . state . searchResults }
renderItem = { ( { item } ) => < Card info = { item . show } /> }
keyExtractor = { item => item . show . id }
/>Au lieu d'utiliser le composant de texte , nous utilisons maintenant la carte et nous la passons via l'attribut d'information qui reçoit l'objet Show .
Voir le fichier card.js que nous utilisons plusieurs fois l'expression this.props.info pour accéder aux valeurs qui ont été transmises lorsque le composant est utilisé. Pour obtenir le nom de la série, nous utilisons this.props.info.name , par exemple.