Vous êtes sur la page 1sur 19

Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

1
Parcours Cours Alternance Employeurs

Accueil > Cours > Développez une application mobile React Native > Manipulez le State

Développez une application mobile React Native

! "2 # 3 30 heures $ Moyenne Licence %&'


Mis à jour le 21/03/2019

( )

Maîtrisez les
Manipulez le State + bases de React ,
Native

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


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

Dans ce chapitre, nous allons découvrir et utiliser l'API TMDB (The Movie DataBase) Native
pour récupérer toutes sortes de films. Vous verrez que l'API TMDB est très
puissante et surtout qu'elle permet de récupérer les informations des films en
/ 0 1
français ! Tout le contenu et la richesse de cette API sont créés par une

communauté de cinéphiles passionnés.

Pour notre application, on souhaite récupérer des films en fonction de la


recherche faite par l'utilisateur. Un petit coup d’œil à la documentation de l'API
TMDB. À première vue, l'API /search correspond à nos attentes :

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 1 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

/search - Text based search is the most common way. You provide a query
string and we provide the closest match. Searching by text takes into account
all original, translated, alternative names and titles.

La recherche fonctionne sur le titre du film et quelle que soit la langue. C'est
parfait.

10:07

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

Récupérez un token de l'API TMDB


,

On va commencer par une étape un peu fastidieuse qui est la récupération d'un
token sur l'API, car oui, même si l'API est gratuite, il faut un token pour l'utiliser.
Celui-ci se récupère en créant un compte et un projet sur l'API.

Le token, en français jeton d'authentification, est une clé de chiffres et de


lettres permettant de vous identifier rapidement, sans avoir à saisir votre
login / mot de passe. Avec ce token, l'API est capable de savoir rapidement
que c'est M. X qui fait l'appel et qu'il a le droit de récupérer les films.

Heureusement pour nous, l'obtention de ce token se fait en quelques minutes. Ce


n'est pas le meilleur moment de ce cours, mais il faut que l'on passe par là si on
souhaite utiliser l'API TMDB.

Première étape, la création d'un compte


: https://www.themoviedb.org/account/signup?language=fr

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 2 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

API TMDB Création d'un compte

Mettez bien une adresse mail valide et à laquelle vous avez accès, car il faut
activer votre compte avec un lien dans le mail reçu.

Vous allez recevoir un mail "Email Verification Required" pour activer votre compte.
Cliquez sur le lien du mail. Vous êtes redirigé vers l'écran de login, connectez-vous
avec les identifiants utilisés précédemment pour la création de votre compte.

Tout en haut à droite, vous devriez voir une pastille avec la première lettre de votre
nom d'utilisateur (moi, c'est le M) :

API TMDB Pastille compte utilisateur

Cliquez sur la pastille, un menu déroulant s'affiche, sélectionnez "Paramètres".


Vous arrivez dans l'écran de réglages de votre compte. Dans le menu à gauche,
une entrée s'appelle "API", cliquez dessus. Vous devriez voir ceci :

API TMDB : Écran réglages API

Assez logiquement, ici, nous allons cliquer sur le lien dans "Demander une clé API".

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 3 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

On nous demande de choisir entre "Développeur" et "Professionnel" :

API TMDB : Développeur ou professionnel ?

Choisissez "Développeur". Vous devez ensuite accepter les termes d'utilisation de


l'API, ce qui résulte en l'affichage d'un formulaire qui ne fait pas rire du tout. Je
vous mets ce que j'ai au début, sur quoi vous pourriez bloquer. Certains champs
sont obligatoires, mais aberrants, comme le lien de l'application. Tant pis, on met
un truc bidon pour que le formulaire soit validé :

API TMDB : Création d'une application

Il faut mettre un peu de texte dans "Résumé de l'application", sinon cela ne passe
pas.

C'est fini, vous arrivez sur un écran où vous retrouvez, tout en bas, le token dont on
a besoin :

API TMDB : Récupération du token

Prenez bien le token dans "Clé de l'API (v3 auth)". Ne faites pas l'erreur de
prendre "Jeton d'accès en lecture à l'API (v4 auth)".

Bravo, vous avez terminé l'étape la plus fastidieuse de ce cours et vous êtes fin

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 4 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

prêt à utiliser toute la puissance de l'API TMDB. Sans plus attendre, je vous propose
de mettre en pratique ce token et de récupérer des films en fonction de la
recherche effectuée.

Récupérez des films depuis l'API

,
C'est une très bonne pratique de séparer la logique API du reste de l'application.
Pour cela, on va créer un nouveau dossier et un nouveau fichier avec tous nos
appels API. Créer un dossier API à la racine de votre projet et, à l'intérieur de celui-
ci, un fichier TMDBApi.js.

Créer une constante avec le token récupéré tout à l'heure :


javascript

1 // API/TMDBApi.js
2
3 const API_TOKEN = "VOTRE_TOKEN_ICI";

Ensuite, on crée une méthode pour rechercher des films en fonction d'un texte et
on constitue l'URL à appeler avec le texte fourni et notre API_TOKEN . Pour savoir
comment construire l'URL, il faut se référer à la documentation de l'API TMDB :
javascript

1 // API/TMDBApi.js
2
3 const API_TOKEN = "VOTRE_TOKEN_ICI";
4
5 export function getFilmsFromApiWithSearchedText (text) {
6 const url = 'https://api.themoviedb.org/3/search/movie?api_key=' +
API_TOKEN + '&language=fr&query=' + text
7
8 }

J'ai défini cette fonction avec export pour que l'on puisse l'utiliser dans
nos components tout à l'heure.

J'ai également rajouté le paramètre &language=fr dans l'URL pour avoir


les résultats des films en français.

Il ne nous reste plus qu'à faire l'appel à l'API. React Native vous propose d'utiliser
l'API Fetch dans sa documentation pour tous vos appels réseaux. Fetch est très
simple à utiliser. On va partir sur cela, mais rien ne vous empêche plus tard
d'utiliser d'autres services pour vos appels réseaux : XMLHttpRequest ou
encore Axios.
javascript

1 // API/TMDBApi.js
2
3 const API_TOKEN = "VOTRE_TOKEN_ICI";
4
5 export function getFilmsFromApiWithSearchedText (text) {
6 const url = 'https://api.themoviedb.org/3/search/movie?api_key=' +
API_TOKEN + '&language=fr&query=' + text
7 return fetch(url)
8 .then((response) => response.json())
9 .catch((error) => console.error(error))

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 5 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

10 }

Ici, on appelle notre URL de recherche avec, en paramètre, le token et le texte


recherché. La fonction then convertit la réponse de notre API en JSON et

la retourne. En cas d'erreur, on passe automatiquement dans le catch et on


affiche une erreur à l'écran.

Dans notre component custom Search, on va appeler cette méthode au clic sur le
bouton "Rechercher". Pour cela, on crée une action sur notre bouton :
jsx

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

Vous avez dû remarquer l'underscore ("_") dans le nom de la méthode


_loadFilms . En Javascript, et dans beaucoup d'autres langages, il n'y a
pas de modificateur public / private. De ce fait, on a pour habitude de
faire précéder le nom des méthodes (et aussi des propriétés) d'un
underscore pour indiquer qu'elles sont privées.

Je précise bien "indiquer", car cela ne rend pas votre méthode privée, vous
pourrez toujours l'appeler n'importe où dans vos fichiers Javascript.
Simplement, c'est un bon moyen de se rendre compte que l'on accède à
une méthode (ou propriété) à laquelle on ne devrait pas accéder.

this._loadFilms() => Oui.


search._loadFilms() => Non. Cela fonctionne toutefois, mais ce

n'est pas bien.

Cette indication est très utilisée en React, vous aurez l'occasion de la voir
dans beaucoup d'exemples sur le web.

Revenons à notre action. On importe la méthode


getFilmsFromApiWithSearchedText du fichier "API/TMDBApi.js" :
javascript

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 6 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

1 // Components/Search.js
2
3 import { getFilmsFromApiWithSearchedText } from '../API/TMDBApi' // import
{ } from ... car c'est un export nommé dans TMDBApi.js

Et enfin, on appelle la méthode au clic sur le bouton "Rechercher" avec un texte


par défaut pour commencer. On verra plus tard comment récupérer le texte de
notre TextInput :
javascript

1 // Components/Search.js
2
3 _loadFilms() {
4 getFilmsFromApiWithSearchedText("star").then(data =>
console.log(data));
5 }

C'est tout bon. Placez-vous sur votre application, mettez votre terminal en
évidence. Cliquez sur le bouton "Rechercher", vous devriez voir apparaître plein de
logs avec des données de films. Je ne mets pas tout, mais cela ressemble à ça :

13:57:54: Object {
13:57:54: "page": 1,
13:57:54: "results": Array [
13:57:54: Object {
13:57:54: "adult": false,
13:57:54: "backdrop_path": "/c4zJK1mowcps3wvdrm31knxhur2.jpg",
13:57:54: "genre_ids": Array [
13:57:54: 12,
13:57:54: 28,
13:57:54: 878,
13:57:54: ],
13:57:54: "id": 11,
13:57:54: "original_language": "en",
13:57:54: "original_title": "Star Wars",
...

Bravo ! Vous venez de réaliser votre tout premier appel sur l'API TMDB.

Bon, afficher des films dans un terminal, c'est bien. Les afficher dans une
application, c'est mieux.

Affichez les films de l'API


,

Pour afficher les films de l'API, il faut déjà les stocker dans une propriété de notre
component. En React, on a pour habitude de définir nos propriétés dans le
constructeur du component. Vous n'êtes pas obligé de faire pareil, mais c'est une
bonne pratique.

On va donc réécrire le constructeur d'un component. Cela ressemble à ça :


javascript

1 // Components/Search.js
2
3 class Search extends React.Component {
4

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 7 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

5 constructor(props) {
6 super(props)
7 // Ici on va créer les propriétés de notre component custom Search
8 }
9
10 //...
11 }

Vous remarquez que le constructeur d'un component a, par défaut, un


paramètre props . Vous comprenez mieux pourquoi on peut faire
this.props dans nos components maintenant. Dès que vous passez
des paramètres à vos components custom, React les récupère, les place
dans un objet props , et initialise votre component avec cet objet.

Je vous invite à créer une propriété _films et à l'initialiser avec un tableau vide
pour l'instant. Vous pouvez également supprimer l'import
import films from '../Helpers/filmsData' , il ne nous servira plus :
javascript

1 // Components/Search.js
2
3 class Search extends React.Component {
4
5 constructor(props) {
6 super(props)
7 this._films = []
8 }
9
10 //...
11 }

On va dire à notre liste de films (FlatList) d'utiliser cette propriété pour gérer ses
données :
jsx

1 // Components/Search.js
2
3 <FlatList
4 data={this._films}
5 keyExtractor={(item) => item.id.toString()}
6 renderItem={({item}) => <FilmItem film={item}/>}
7 />

Il ne nous reste plus qu'à modifier notre propriété _films avec les films
récupérés depuis l'API TMDB et à mettre à jour notre liste de données. Si
vous faites attention aux logs que l'on a affichés tout à l'heure lors de l'appel API,
vous avez pu voir que les films sont stockés dans un tableau results . On va
donc récupérer nos films dans ce tableau :
javascript

1 // Components/Search.js
2
3 _loadFilms() {
4 getFilmsFromApiWithSearchedText("star").then(data => {
5 this._films = data.results
6 this.forceUpdate()

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 8 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

7 })
8 }

La méthode forceUpdate() permet de forcer un component à se


rendre à nouveau. On va de nouveau passer dans la méthode render de
notre component. Cette fois _films contient les films de l'API et notre
liste de données va les afficher. Notez bien que la méthode
forceUpdate() re-rend TOUT le component. Ici le TextInput, le Button
et la FlatList sont re-rendus.

Basculez sur votre application, un reload sera sûrement nécessaire. Cliquez sur le
bouton "Rechercher" :

FlatList avec les films récupérés depuis l'API TMDB

Yes ! Ce n'était pas si compliqué, n'est-ce pas ? Allez-y, scrollez dans la liste des
films ! Vous allez retrouver vos films récupérés depuis l'API.

Bon, je suis désolé, je casse un peu l'ambiance, mais en fait, on a fait un truc pas
bien du tout ici. On a forcé un component à se re-rendre avec la méthode
forceUpdate() . C'est une chose à éviter.

D'accord, mais si on n'appelle plus la méthode forceUpdate() , notre


component ne va pas se re-rendre et on ne verra jamais notre liste de films
se mettre à jour ?

C'est vrai, mais je vais vous montrer une solution beaucoup plus propre et efficace
pour re-rendre un component. C'est une solution qui existe depuis longtemps
dans le développement web : le State.

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 9 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

Le State

,
Pour vous présenter le state, je vais m'appuyer sur la définition faite par React
Native, elle est très parlante.

Différence entre prop et state


Pour contrôler un component, il y a deux types de données. Les props et le state.

Les props (que l'on a déjà vues) sont fixées par le component parent et ne
peuvent pas être modifiées par le component qui les reçoit. Par exemple, pour
nos items FilmItem, on a défini, depuis le component parent Search, une prop
film :
jsx

1 renderItem={({item}) => <FilmItem film={item}/>}

Une fois dans le component FilmItem, on peut récupérer le film via


this.props.film , mais on ne peut pas le modifier et afficher un autre film à la
place, par exemple. Vous pouvez toujours essayer de faire
this.props.film = {données d'un autre film} dans le component
FilmItem, cela n'aura aucun effet. Les props sont, en langage plus
technique, accessibles en lecture uniquement.

Attention, toutefois, à ne pas faire de raccourci trop vite. Ne pensez pas que
les props d'un component ne peuvent pas changer. Elles le peuvent ;
simplement, c'est le component parent qui va les changer.

Si, dans notre exemple précédent, vous souhaitez changer le film affiché
dans un component FilmItem, c'est bien le component parent, le
component Search, qui va lui fournir les nouvelles props.

Il nous manque donc un élément pour modifier notre component et ses


données affichées. C'est là qu'intervient le state.

Dès lors que vous souhaitez modifier votre component et ses données
affichées, vous allez utiliser son state.

Dans notre component Search, on gère un tableau de films que l'on affiche
ensuite dans une FlatList. Ce tableau de films est modifié à chaque fois que l'on
appelle l'API TMDB. C'est l'exemple parfait pour utiliser le state.

Initialisez le state
Comme pour les variables d'un component, on a pour habitude d'initialiser le state
dans le constructeur du component. On va donc initialiser notre state avec un
tableau de films vide :
javascript

1 // Components/Search.js
2

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 10 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

3 constructor(props) {
4 super(props)
5 this.state = { films: [] }
6 }

Le nom de cette propriété est fixe, vous ne pouvez pas le changer. Si vous
faites this.myState = ... , par exemple, vous créez juste une variable
qui n'a rien à voir avec le state.

Ensuite, on va dire à notre FlatList d'utiliser cette nouvelle donnée pour afficher ses
films :
jsx

1 // Components/Search.js
2
3 <FlatList
4 data={this.state.films}
5 keyExtractor={(item) => item.id.toString()}
6 renderItem={({item}) => <FilmItem film={item}/>}
7 />

Il ne nous reste plus qu'à modifier le state avec les films récupérés depuis l'API.

Modifiez le state

Pour modifier la valeur films de votre state, je suis sûr que vous avez pensé à

faire : this.state.films = data.results . Cela va fonctionner, mais vous serez


obligé de faire un forceUpdate() juste après pour que votre FlatList se mette à
jour et affiche vos nouveaux films. C'est exactement ce que nous souhaitons éviter
de faire, ce n'est donc pas la bonne solution.

En React, pour modifier une donnée du state, on passe toujours par setState
.

D'accord, mais pourquoi ? Il fait quoi exactement, ce setter ?

setState récupère les modifications de vos données et indique à React que le


component a besoin d'être re-rendu avec ces nouvelles données.

Commençons par enlever ce monstrueux forceUpdate() de notre application

et utilisons setState lors de la récupération des films de l'API :


javascript

1 // Components/Search.js
2
3 _loadFilms() {
4 getFilmsFromApiWithSearchedText("star").then(data => {
5 this.setState({ films: data.results })
6 })
7 }

Retournez sur votre application. Rechargez-la si nécessaire. Cliquez sur le bouton

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 11 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

"Rechercher" et TADAAM :

Mise à jour de la liste de données avec setState

Que s'est-il passé exactement ici ?

Nous avons modifié les données de notre component Search, le state, en passant
par la fonction setState . React a identifié que le state de votre component
Search a changé. Il va alors demander à votre component Search de se re-rendre
avec le nouveau state. Tout votre component Search est re-rendu et, cette fois,
this.state.films contient la liste des films de l'API. Votre FlatList utilise ces
nouvelles données et les affiche.

Vous ne me croyez pas quand je vous dis que le component est entièrement re-
rendu ? Vous avez raison de ne pas me croire sur parole. Je vous propose une
petite démonstration. Ajoutez un log dans la méthode render de votre
component :
jsx

1 // Components/Search.js
2
3 render() {
4 console.log("RENDER")
5 return (
6 ...
7 )
8 }

Au lancement de l'application, vous devriez voir :

09:06:02: RENDER

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 12 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

C'est normal, au premier affichage du component, celui-ci est rendu. Au clic sur le
bouton "Rechercher", on peut voir :

09:06:02: RENDER
09:06:05: RENDER

Je ne vous ai pas menti. Une fois setState appelé, TOUT le component est re-
rendu.

React préconise fortement de n'utiliser que les données provenant des props et
du state dans le render de vos component. Ainsi, vous vous assurez que vos
components sont toujours mis à jour dès que leurs informations changent.

C'est une excellente pratique que l'on a toujours utilisée dans ce cours, sans
vraiment s'en rendre compte. Si vous regardez le render de notre
component FilmItem, vous verrez que l'on n'utilise que des données
provenant des props.

Je ne veux plus voir de forceUpdate() dans vos applications à présent. Utiliser


toujours les props et le state pour mettre à jour vos components.

N'abusez pas du state

,
Une erreur que l'on commet régulièrement, moi le premier, est d'utiliser le state à
tout va pour gérer toutes les données d'un component. Vous allez voir, dans la
prochaine fonctionnalité que l'on va mettre en place, que, parfois, utiliser le state
pour gérer une donnée de notre component est une mauvaise idée.

Dans notre application, actuellement, on fait toujours la même recherche de films


avec "Star". Je veux à présent utiliser le texte saisi dans mon TextInput.

Récupérer la valeur d'un Component


Première étape, il nous faut récupérer la valeur de notre TextInput.

Facile. Quand l'utilisateur clique sur le bouton "Rechercher", je récupère la


valeur du TextInput, non ?

Oui, pourquoi ne pas faire quelque chose comme : monTextInput.getText() ?


C'est ce que je cherchais souvent à faire au début de mon apprentissage de
React. Mais cela ne fonctionne pas comme ça.
En React, vous devez penser différemment. Si vous souhaitez récupérer la valeur
d'un component, il faut qu'un évènement ait lieu sur ce component.

Pour l'instant, le seul évènement qui survient sur notre TextInput, c'est
l'évènement onChangeText , appelé à chaque fois que l'utilisateur saisit un
caractère. Si vous me suivez toujours, cela signifie que, pour être sûr d'avoir la
bonne valeur du TextInput, vous devez la récupérer à chaque fois que l'utilisateur

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 13 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

saisit un caractère.

Si vous ne récupérez pas la valeur pendant la saisie et que l'utilisateur clique sur le
bouton "Rechercher", c'est foutu ! L'évènement appelé par le clic est l'évènement
onPress du Button. Aucun évènement n'a lieu sur le TextInput à cet instant,
vous ne pourrez pas récupérer le texte du TextInput.

Nous allons donc récupérer le texte saisi à chaque caractère saisi et, pour vous
montrer pourquoi il ne faut pas stocker n'importe quelle donnée dans le state, on
va stocker le texte dans le state :
jsx

1 // Components/Search.js
2
3 class Search extends React.Component {
4 constructor(props) {
5 super(props)
6 this.state = {
7 films: [],
8 searchedText: "" // Initialisation de notre donnée searchedText
dans le state
9 }
10 }
11
12 _searchTextInputChanged(text) {
13 this.setState({ searchedText: text })
14 }
15
16 render() {
17 console.log("RENDER")
18 return (
19 <View style={styles.main_container}>
20 <TextInput
21 style={styles.textinput}
22 placeholder='Titre du film'
23 onChangeText={(text) => this._searchTextInputChanged(text)}
24 />
25 //...
26 </View>
27 )
28 }
29 }

Ici, j'ai défini une propriété searchedText dans mon state et, à chaque
modification du texte du TextInput, j'appelle setState pour mettre à jour ma
propriété searchedText de mon state.

Maintenant, on va vérifier que tout fonctionne et on va appeler notre recherche de


films avec le texte récupéré du TextInput, et uniquement si le texte n'est pas vide :
javascript

1 // Components/Search.js
2
3 _loadFilms() {
4 console.log(this.state.searchedText) // Un log pour vérifier qu'on a
bien le texte du TextInput
5 if (this.state.searchedText.length > 0) { // Seulement si le texte
recherché n'est pas vide
6 getFilmsFromApiWithSearchedText(this.state.searchedText).then(data =>
{

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 14 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

7 this.setState({ films: data.results })


8 })
9 }
10 }

Lancez l'application, saisissez du texte dans le TextInput, par exemple "Harry",


et cliquez sur le bouton pour faire une recherche.

Dans les logs, on a :

19:05:01 Harry

Cela fonctionne, on récupère bien le bon texte dans le TextInput et côté


application :

Texte du TextInput stocké dans le state et lancement d'une


recherche

Et bien, c'est quoi ton problème, là ? Ça marche super bien !

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 15 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

Vous avez raison, cela marche, mais je vais vous montrer le problème ici. Ajoutez
un log tout simple, comme tout à l'heure, dans le render de notre component
Search :
jsx

1 // Components/Search.js
2
3 render() {
4 console.log("RENDER")
5 return (
6 ...
7 )
8 }

Lancez votre application, vous devriez avoir un premier log montrant que l'on
appelle bien le render de notre component à son initialisation :

19:10:10 RENDER

Maintenant, saisissez du texte dans le TextInput, comme tout à l'heure "Harry",


mais n'appuyez pas sur le bouton "Rechercher" et regardez bien vos logs. Vous
devriez voir ceci :

19:10:10 RENDER
19:10:10 RENDER
19:10:10 RENDER
19:10:10 RENDER
19:10:10 RENDER

Vous voyez le problème ici ?

On vient de re-rendre notre component Search 5 fois, une fois pour chaque lettre
saisie. Et le pire dans tout cela est qu'on l'a re-rendu pour rien. Notre component
Search a les mêmes informations affichées qu'avant de le re-rendre 5 fois. On n'a
pas ajouté, modifié ou supprimé de films et le rendu reste le même.

Cette observation me permet de vous introduire une très bonne pratique. Dans le
state, on ne gère que des données qui, une fois modifiées, peuvent affecter le
rendu de notre component.

Nos films modifient l'affichage de notre component, ils ont donc leur place
dans le state.
Le texte du TextInput ne modifie pas l'affichage de notre component, il n'a
pas sa place dans le state.

Re-rendre un component reste un processus lourd, il ne faut pas en abuser. Même


si notre application fonctionne très bien actuellement, sur des components plus
importants, plus long à re-rendre, vous risquez d'avoir des problèmes de
performances.

Souvent, si on utilise une donnée dans le render de notre component,

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 16 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

comme ici avec les films, c'est qu'elle a sa place dans le state. Autrement, sa
place dans le state peut être remise en question.

Je donne peut-être l'impression qu'on a fait quelque chose de très mauvais


ici mais, en réalité, non. Vous verrez beaucoup d'exemples sur le web où
le changement d'une donnée d'un component est gérée avec le state, sans
qu'un re-rendu soit nécessaire.

C'est tout simplement parce que ce n'est pas grave en soit et que le re-
rendement des components est très bien géré et optimisé par React.

Simplement, je souhaite éviter avec vous une pratique que j'ai pu retrouver
sur certaines applications et qui consiste à tout mettre dans le state, sans
se poser de questions.

Ici, on va plutôt gérer le texte de notre TextInput comme une simple variable de
notre component :
jsx

1 // Components/Search.js
2
3 import React from 'react'
4 import { StyleSheet, View, TextInput, Button, Text, FlatList } from 'react-
native'
5 import FilmItem from './FilmItem'
6 import { getFilmsFromApiWithSearchedText } from '../API/TMDBApi'
7
8 class Search extends React.Component {
9
10 constructor(props) {
11 super(props)
12 this.searchedText = "" // Initialisation de notre donnée searchedText
en dehors du state
13 this.state = {
14 films: []
15 }
16 }
17
18 _loadFilms() {
19 if (this.searchedText.length > 0) { // Seulement si le texte recherché
n'est pas vide
20 getFilmsFromApiWithSearchedText(this.searchedText).then(data => {
21 this.setState({ films: data.results })
22 })
23 }
24 }
25
26 _searchTextInputChanged(text) {
27 this.searchedText = text // Modification du texte recherché à chaque
saisie de texte, sans passer par le setState comme avant
28 }
29
30 render() {
31 console.log("RENDER")
32 return (
33 <View style={styles.main_container}>
34 <TextInput
35 style={styles.textinput}

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 17 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

36 placeholder='Titre du film'
37 onChangeText={(text) => this._searchTextInputChanged(text)}
38 />
39 <Button title='Rechercher' onPress={() => this._loadFilms()}/>
40 <FlatList
41 data={this.state.films}
42 keyExtractor={(item) => item.id.toString()}
43 renderItem={({item}) => <FilmItem film={item}/>}
44 />
45 </View>
46 )
47 }
48 }
49
50 const styles = StyleSheet.create({
51 main_container: {
52 flex: 1,
53 marginTop: 20
54 },
55 textinput: {
56 marginLeft: 5,
57 marginRight: 5,
58 height: 50,
59 borderColor: '#000000',
60 borderWidth: 1,
61 paddingLeft: 5
62 }
63 })
64
65 export default Search

Vous pouvez tester et constater que notre application fonctionne tout aussi
bien sans utiliser le texte du TextInput dans le state. Côté logs, on n'a plus que deux
appels au render du component Search :

19:14:20 RENDER
19:14:25 RENDER

Un à l'initialisation du component et un lorsqu'on lance une recherche et qu'on


affiche de nouveaux films.

On arrive à la fin de ce chapitre et on a plutôt bien avancé dans notre application,


non ? À présent, vous êtes capable de faire des appels API, de récupérer des
données et les afficher.

Mais surtout, vous savez manipuler et utiliser le state, sans trop en abuser, hein ?
C'est un concept très important en React. Le state et les props gèrent les
données de vos components.

Le super setState vous assure de re-rendre vos components dès que c'est
nécessaire. Fini les forceUpdate() . En utilisant setState , on laisse
React utiliser toute sa puissance pour gérer nos components et, pour l'instant, cela
marche plutôt bien.

On a découvert beaucoup de concepts depuis le début de cette partie :


components, styles, props, appel réseau et state. À vrai dire, on a tout vu, en tout
cas, tous les concepts liés à React et React Native. On va donc faire une petite

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 18 sur 19


Manipulez le State - Développez une application mobile React Native - OpenClassrooms 09/04/2019 13)00

pause. Au lieu de vous apprendre de nouvelles choses, autour de React Native, on


va consolider nos bases et pratiquer sur tout ce qu'on a appris. Cela vous dit ? Et
pour commencer, je vous propose d'améliorer notre component Search et d'y
ajouter quelques fonctionnalités.

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

AJOUTEZ DES
+ UTILISEZ LES PROPS FONCTIONNALITÉS SUR UN ,
COMPONENT

Le professeur Découvrez aussi ce cours en...


Maxime Charruel
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 0 / 6 7 8

Forum Conditions Générales

Blog d'Utilisation

Nous rejoindre Politique de Protection


des Données
Personnelles

Nous contacter

https://openclassrooms.com/fr/courses/4902061-developpez-une-application-mobile-react-native/4915721-manipulez-le-state Page 19 sur 19