Vous êtes sur la page 1sur 13

Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

1
Parcours Cours Alternance Employeurs

Accueil > Cours > Développez une application mobile React Native > Ajoutez des fonctionnalités sur un
component

Développez une application mobile React


Native

! "/ # 0 30 heures $ Moyenne Licence %&'


Mis à jour le 21/03/2019

( )

Maîtrisez les
Ajoutez des fonctionnalités sur un + bases de React ,
Native
component
1. Faites vos premiers
pas avec les
components React

2. Appliquez des
styles à vos
components

3. Construisez vos
vues avec Flexbox

4. Utilisez les Props

5. Manipulez le State

6. Ajoutez des
fonctionnalités sur
00:31 un component

7. Appréhendez le
"setState"

. - Quiz : Maîtrisez les


bases de React
* Pour télécharger les vidéos de ce cours, devenez Premium Native

Dans ce chapitre, nous allons revoir des notions et concepts

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 1 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

appris précédemment, afin de vous perfectionner dans leur


1 2 3
utilisation. On ne verra donc rien de nouveau. Rassurez-vous,
même si vous n'êtes pas bien réveillé, ce chapitre devrait bien se
passer.

Vous allez voir qu'avec tout ce que l'on a déjà appris, on est en
mesure de créer des fonctionnalités vraiment sympas et très
rapidement.

Au programme, je vous propose d'ajouter 3 fonctionnalités dans


notre component Search :

ajouter un composant de chargement pour faire patienter


l'utilisateur pendant la récupération des films de l'API ;
valider la recherche avec le clavier, en plus de la validation
avec le bouton "Rechercher" ;
rendre notre liste de films plus "lisible", en afficher le poster
du film, parce que, oui, on a toujours notre rectangle gris.
Alors, commençons par cela.

06:27

* Pour télécharger les vidéos de ce cours, devenez Premium

Récupérez le poster d'un film


,

Si vous avez regardé attentivement le JSON renvoyé par l'API, très


attentivement, vous avez dû remarquer un champ ressemblant

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 2 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

à ceci :
json

1 "poster_path": "/dHhyFNvAGnc1vtXWXWnnEfG1dLO.jpg"

On a donc le nom de l'image, mais cela s'arrête là. Il nous manque


tout le début de l'URL. On va donc créer une fonction pour
construire l'URL d'une image et on va le faire dans notre fichier
API/TMDBApi.js :
javascript

1 // API/TMDBApi.js
2
3 export function getImageFromApi (name) {
4 return 'https://image.tmdb.org/t/p/w300' + name
5 }

Ici, je vous avoue que vous n'auriez pas pu le deviner, en tout cas
pour l'URL complète. L'API TMDB nous permet également de
récupérer une taille particulière pour notre image. Ici, j'ai demandé
une image avec une largeur de 300.

À présent, il ne nous reste plus qu'à ajouter notre image dans le


component Image des items FilmItem. N'oubliez pas l'import de
la fonction getImageFromApi :
jsx

1 // Components/FilmItem.js
2
3 import { getImageFromApi } from '../API/TMDBApi'
4
5 // ...
6
7 <Image
8 style={styles.image}
9 source={{uri: getImageFromApi(film.poster_path)}}
10 />

Rien de très compliqué ici : on définit la source de notre image


avec l'URL construite par notre fonction getImageFromApi .

Jetez un œil côté application, lancez une recherche :

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 3 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

Récupération des posters des films de l'API TMDB

C'est quand même plus joli comme ça. Vous pouvez également
enlever le style backgroundColor gris que l'on a mis sur l'image, il
ne sert plus à présent.

Validation de la recherche avec le


,

clavier
On continue avec une fonctionnalité très facile à mettre en place et
qui offre une bien meilleure expérience utilisateur. Actuellement,
pour rechercher des films, on tape du texte dans notre TextInput et
on clique sur le Button "Rechercher". Certains utilisateurs, comme
moi, ont l'habitude d'appuyer sur le bouton "Envoyer" du clavier
pour valider un TextInput. C'est très facile à faire, mais cela a le
mérite de vous faire rechercher dans la documentation React
Native.

Je vous invite donc à consulter les props possibles sur un


TextInput et à identifier la prop qui semble correspondre au mieux
à notre fonctionnalité.

Alors, vous avez trouvé ?

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 4 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

On va utiliser la prop onSubmitEditing :

Callback that is called when the text input's submit button is


pressed. Invalid if multiline={true} is specified.

On n'est pas dans le cas d'un TextInput multilignes ; c'est


exactement ce que l'on souhaite mettre en place. On ajoute donc
cette prop à notre TextInput et, vu que l'on a déjà une fonction
pour lancer la recherche, on va la réutiliser :
jsx

1 <TextInput
2 style={styles.textinput}
3 placeholder='Titre du film'
4 onChangeText={(text) =>
this._searchTextInputChanged(text)}
5 onSubmitEditing={() => this._loadFilms()}
6 />

Voilà comment, en quelques minutes, améliorer l'expérience

utilisateur de votre application. On continue.

Affichage d'un chargement lors de


,
la recherche
On a de la chance, l'API TMDB répond très rapidement aux appels
qu'on lui fait. De plus, sauf si vous êtes actuellement au sommet du
Mont Blanc, vous devez voir les films s'afficher instantanément.
Toutefois, la connexion de votre utilisateur varie souvent,
parfois elle monte très haut, parfois elle descend très bas. Dans le
cas où sa connexion ralentirait, il connaîtrait une très mauvaise
expérience utilisateur. Il s'agit du "bouton qui ne change rien".

Votre utilisateur va lancer une recherche en cliquant sur le bouton


"Rechercher" ou "Envoyer" du clavier. Vous allez lancer l'appel API
et attendre son retour. Entre l'appui sur le bouton et le retour de
l'API, il ne se passe rien sur notre application. Si le retour API met 5
secondes, pendant 5 secondes, l'utilisateur attend, ne voit aucun
changement et va avoir l'impression que le bouton ne fait rien.
Pour pallier cette incompréhension, rien de mieux que d'afficher
un chargement à l'écran.

J'insiste beaucoup sur l'expérience utilisateur, mais, croyez-


moi, c'est l'élément qui fait la différence. Votre application
peut être aussi utile et innovante que souhaité, si

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 5 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

l'expérience utilisateur est mauvaise, l'utilisateur passera à


autre chose.

En plus, personnellement, quand l'appui sur un bouton ne


fait rien, j'ai tendance à appuyer encore plus dessus, ce qui
améliore rarement les choses.

React Native met à disposition un component React Native


spécialement pour les chargements : l'ActivityIndicator. Avec ce
component, je veux que vous mettiez en place ceci :

Démonstration ActivityIndicator sur iOS et


Android

Remarquez la différence de rendu de l'ActivityIndicator


entre iOS et Android. Encore une fois, React Native nous
prouve qu'il affiche bien à l'écran les composants natifs sur
iOS et Android.

Posez-vous la question : que souhaite-t-on faire ici


exactement ?

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 6 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

On souhaite afficher un chargement ActivityIndicator au


lancement de la recherche par-dessus notre FlatList. Puis, à la fin
de l'appel API, on souhaite juste enlever le chargement.

Gestion du chargement

Première question à se poser : est-ce qu'une variable


isLoading , pour afficher ou masquer notre chargement,
a sa place dans le state ?

Oui, on veut qu'à son chargement, avec setState , notre


component Search soit re-rendu pour afficher, ou non, le
chargement.

Je vous invite donc à rajouter un booléen isLoading dans notre


state :
javascript

1 // Components/Search.js
2
3 this.state = {
4 films: [],
5 isLoading: false // Par défaut à false car il n'y a pas de
chargement tant qu'on ne lance pas de recherche
6 }

Ensuite, on va gérer le lancement du chargement et son arrêt. Si


vous me suivez jusque là, on doit lancer le chargement quand on
fait l'appel à l'API et l'arrêter quand l'API nous retourne les films :
javascript

1 // Components/Search.js
2
3 _loadFilms() {
4 if (this.searchedText.length > 0) {
5 this.setState({ isLoading: true }) // Lancement du
chargement
6
getFilmsFromApiWithSearchedText(this.searchedText).then(data
=> {
7 this.setState({
8 films: data.results,
9 isLoading: false // Arrêt du chargement
10 })
11 })
12 }
13 }

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 7 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

N'oubliez pas de toujours passer par setState pour


manipuler votre state.

On peut déjà vérifier que notre booléen gère correctement le


chargement. Ajoutez un log dans le render du component Search :
javascript

1 // Components/Search.js
2
3 render() {
4 console.log(this.state.isLoading)
5 return ( ... )
6 }

Sur l'application, rechargez la vue, saisissez du texte dans le


TextInput et cliquez sur le bouton "Rechercher".

Vous devriez voir, dans vos logs, quelque chose comme ceci :

13:49:32: false
13:49:33: true
13:49:33: false

Ça marche. Notre booléen qui gère le chargement passe bien à


true pendant l'appel à l'API, puis à false quand l'API nous retourne
les films. On peut continuer.

À présent, il faut :

pendant le chargement, afficher notre ActivityIndicator ;


en dehors du chargement, enlever notre ActivityIndicator.

Gestion de l'ActivityIndicator
On va créer une fonction qui va gérer tout cela pour nous et, vous
allez le voir, c'est très simple :
jsx

1 // Components/Search.js
2
3 import { ..., ActivityIndicator } from 'react-native'
4
5 class Search extends React.Component {
6
7 // ...
8
9 _displayLoading() {
10 if (this.state.isLoading) {
11 return (
12 <View style={styles.loading_container}>

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 8 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

13 <ActivityIndicator size='large' />


14 {/* Le component ActivityIndicator possède une
propriété size pour définir la taille du visuel de
chargement : small ou large. Par défaut size vaut small, on
met donc large pour que le chargement soit bien visible */}
15 </View>
16 )
17 }
18 }
19
20 // ...
21 }

javascript

1 // Components/Search.js
2
3 const styles = StyleSheet.create({
4 ...
5 loading_container: {
6 position: 'absolute',
7 left: 0,
8 right: 0,
9 top: 100,
10 bottom: 0,
11 alignItems: 'center',
12 justifyContent: 'center'
13 }
14 })

Le style position: 'absolute' permet de positionner


des éléments dans la vue sans tenir compte des autres
éléments de la vue. Depuis le début du cours, on fait
l'inverse, c'est-à-dire que l'on positionne nos éléments
relativement par rapport aux autres éléments (par défaut
position: 'relative' ).

La définition de la position absolute va nous permettre


de faire passer le chargement par-dessus notre FlatList.
Pour les adeptes du CSS, ce style n'est pas nouveau. Le
problème est que le style position: 'absolute' fait
passer notre chargement par-dessus toute notre vue, y
compris le TextInput et le Button "Rechercher". Si vous
affichez une vue par dessus des éléments, ces derniers
ne sont plus accessibles. On définit donc une valeur top à
100 pour notre vue, pour qu'elle ne bloque pas l'accès
au TextInput et au Button "Rechercher".

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 9 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

Pourquoi crées-tu une View dans laquelle tu mets ton


ActivityIndicator, au lieu de créer juste un ActivityIndicator ?

Je souhaite centrer mon ActivityIndicator dans l'espace occupé


par ma FlatList normalement. Je commence donc par créer une
View qui va occuper tout l'espace dans mon écran, ou plutôt,
quasiment tout l'espace :
top: 100, left: 0, right: 0, bottom: 0 . Ensuite, rappelez-
vous, lorsque l'on souhaite définir l'alignement de nos
components, il faut appliquer les styles d'alignement sur le
component parent. Ici, je souhaite aligner mon ActivityIndicator,
j'applique donc les styles d'alignement sur son component parent,
ma View. Par défaut, le style flexDirection vaut 'column' , le
justifyContent: 'center' centre donc mon component sur
l'axe vertical Y, et le alignItems: 'center' centre mon
component sur l'axe horizontal X. Même si vous aviez sûrement
compris le fonctionnement ici, cela ne fait pas de mal de faire une
piqûre de rappel sur les styles.

À présent, on va modifier le rendu de notre component pour


appeler cette fonction et afficher, ou non, le chargement :
jsx

1 // Components/Search.js
2
3 render() {
4 return (
5 <View style={styles.main_container}>
6 <TextInput
7 style={styles.textinput}
8 placeholder='Titre du film'
9 onChangeText={(text) =>
this._searchTextInputChanged(text)}
10 onSubmitEditing={() => this._loadFilms()}
11 />
12 <Button title='Rechercher' onPress={() =>
this._loadFilms()}/>
13 <FlatList
14 data={this.state.films}
15 keyExtractor={(item) => item.id.toString()}
16 renderItem={({item}) => <FilmItem film={item}/>}
17 />
18 {this._displayLoading()}
19 </View>
20 )
21 }

Allez-y, essayez ! Placez-vous sur votre device et lancez une

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…ct-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 10 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

recherche. Vous devriez voir apparaître un chargement qui


s'affiche, puis se masque lorsque les films sont récupérés.

Je suis passé un peu vite ici, mais vous avez vu que l'on peut
appeler des fonctions dans le render de notre component.
Attention, toutefois, ces fonctions appelées dans le render
doivent obligatoirement retourner des éléments
graphiques, soit en React Native, des components (React
Native ou custom). Vous pouvez toujours essayer de
retourner autre chose, return "Coucou" , par exemple.
Cela ne fonctionnera pas et votre application va planter.

Tout dans le render


Dans mon exemple précédent, j'ai créé une fonction
_displayLoading() pour afficher, ou non, le chargement. J'ai en
quelque sorte externalisé le rendu du chargement. Vous vous êtes
peut-être demandé pourquoi ne pas tout laisser dans le render de
notre component. C'est tout à fait possible, on peut très bien faire :
jsx

1 // Components/Search.js
2
3 render() {
4 return (
5 <View style={styles.main_container}>
6 <TextInput
7 style={styles.textinput}
8 placeholder='Titre du film'
9 onChangeText={(text) =>
this._searchTextInputChanged(text)}
10 onSubmitEditing={() => this._loadFilms()}
11 />
12 <Button title='Rechercher' onPress={() =>
this._loadFilms()}/>
13 <FlatList
14 data={this.state.films}
15 keyExtractor={(item) => item.id.toString()}
16 renderItem={({item}) => <FilmItem film={item}/>}
17 />
18 { this.state.isLoading ?
19 <View style={styles.loading_container}>
20 <ActivityIndicator size='large' />
21 </View>
22 : null
23 }
24 </View>
25 )
26 }

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 11 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

Honnêtement, cela se défend très bien comme solution. On garde


toute la logique du render de notre component, dans son
render .

Pourtant, en React Native, on utilise assez peu cette solution. Le


problème, quand vous déclarez un test directement dans le
render du component, est que vous êtes obligé de passer par
une condition en ligne, vous savez cette syntaxe
test ? vrai : faux . Ici, c'est n'est pas très propre, car, dans le
cas où le chargement est fini, on est obligé de retourner null (ligne
15). De plus, avec les conditions en ligne, si vous devez faire deux
actions différentes, cela va ( if else ). Si c'est plus complexe (
if elseif if else etc. ), cela devient vite difficile à mettre en
place.

Je ne vous impose pas l'une ou l'autre solution, je vous


présente juste les deux façons de faire. C'est à vous de faire
votre choix. Toutefois, je le rappelle, mais vous allez très
souvent retrouver sur le web la première solution, où le
rendu est externalisé dans une fonction du component.

J'avais pas mal de choses à vous dire sur le rendu "conditionnel"


dans vos components. C'est un point important auquel vous serez
confronté lors de la réalisation d'applications plus fonctionnelles et
plus poussées.

Notre chargement est en place, parfait.

Et... c'est terminé. Eh oui, on a déjà mis en place les 3


fonctionnalités que l'on voulait. C'était rapide, n'est-ce pas ?

Vous voyez qu'avec tout ce que l'on a déjà appris, on est capable
de créer des fonctionnalités vraiment sympas, simplement et très
rapidement.

Dans le prochain chapitre, nous allons ajouter une autre


fonctionnalité à notre component Search. Cette fonctionnalité va
mettre en évidence une spécificité de setState . Car oui,
setState nous cache des choses.

4 J'AI TERMINÉ CE CHAPITRE ET JE PASSE AU SUIVANT

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…act-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 12 sur 13


Ajoutez des fonctionnalités sur un component - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)02

APPRÉHENDEZ LE
+ MANIPULEZ LE STATE ,
"SETSTATE"

Le professeur Découvrez aussi ce cours


Maxime Charruel en...
Développeur Mobile : iOS / Android / React
Native. "
Premium

Vidéo

OpenClassrooms Entreprises En plus 5 Français

L'entreprise Employeurs Devenez mentor

Alternance Aide et FAQ 2 1 6 7 8

Forum Conditions

Blog Générales
d'Utilisation
Nous rejoindre
Politique de
Protection des
Données
Personnelles

Nous contacter

https://openclassrooms.com/fr/courses/4902061-developpez-une-ap…ct-native/4916051-ajoutez-des-fonctionnalites-sur-un-component Page 13 sur 13

Vous aimerez peut-être aussi