Créer des applications mobiles avec React Native

Auteur: Mohamed CHINY Durée necessaire pour le cours de Créer des applications mobiles avec React Native Niveau recommandé pour le cours de Créer des applications mobiles avec React Native Supports vidéo non disponibles pour ce cours Exercices de renforcement non disponibles pour ce cours Quiz non disponibles pour ce cours

Page 10: Le hook useMemo pour mémoriser un résultat

Toutes les pages

Le hook useMemo

Mémoriser le résultat d'un calcul couteux

Le hook useMemo en React Native (et en React aussi) est une fonction qui permet de mémoriser le résultat d’un calcul afin d’éviter de le recalculer à chaque re-rendu (re-rendering) du composant, sauf si ses dépendances changent.

Le hook useMemo prend en paramètre une fonction de calcul qui retourne le résultat calculé et un tableau de dépendances. La fonction ne se réexécute que si l’une des dépendances est modifiée. Cela permet d’optimiser les performances en évitant des opérations inutiles, notamment dans les cas où le calcul est coûteux. useMemo est donc particulièrement utile pour améliorer l’efficacité des composants fonctionnels dans des interfaces complexes ou dynamiques.

La structure du hook useMemo ressemble à ceci:
const valeur_à_mémoriser = useMemo(() => {
   return résultat_de_calcul
},[dépendance])
La variable valeur_à_mémoriser stocke le résultat retourné par useMemo, dans ce cas résultat_de_calcul. La valeur à mémoriser persiste entre les rendus et n'est donc pas calculée suite à chaque re-rendering, sauf si la variable dépendance change. Dans ce cas, le calcul est réexécuté afin d'actualiser la valeur à mémoriser.
Le tableau des dépendance peut contenir plusieurs éléments et pas qu'un seul. Ces éléments sont généralement des states.

Exemple d'utilisation de useMemo

Imaginez que l'on souhaite calculer le carré d'un nombre et afficher le résultat dans un composant Text. Si on veut éviter de recalculer ce carré là à chaque re-rendering, on va le stocker dans une variable à l'aide du hook useMemo. On supposera que le nombre dont on veut calculer le carré sera saisi par l'utilisateur dans un composant InputText.
Le calcul du carré n'est pas toujours une opération couteuse, mais je voulais juste vous montrer comment utiliser useMemo, ensuite ça sera à vous de décider quand il sera utile de vous en servir.
Je propose ce code:
import { useState, useMemo } from 'react';
import { StyleSheet, TextInput, View, Text } from 'react-native';

export default function App() {
   const [nbr,setNbr]=useState('0')
   const carre=useMemo(()=>{
      console.log("Calcul du carré du nombre "+nbr)
      const nombre=parseInt(nbr)
      return isNaN(nombre)?"Aucun nombre spécifié":nombre**2
   },[nbr])

   return (
      <View style={styles.container}>
         <Text>{carre}</Text>
         <TextInput value={nbr.toString()}
         style={{borderWidth:1, width:200, margin:10}}
         keyboardType="numeric"
         onChangeText={setNbr} />
      </View>
   );
}

const styles = StyleSheet.create({
   container: {
      flex: 1,
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
   },
});
Après exécution on obtient ce résultat:
0
Passons à l'explicaiton:

On commence par importer les modules useState et useMemo à partir de la librairie 'React':
import { useState, useMemo } from 'react';
La valeur que l'on souhaite mémoriser est le carré de nbr qui est un state qu'on a créé ainsi:
const [nbr,setNbr] = useState('0')
Remarquez que la valeur initiale du state est une chaîne de caractères. En effet, si on souhaite l'afficher dans le composant TextInput, alors il faut que ce soit une chaîne de caractères. Sinon, assurez-vous juste de lui appliquer la méthode .toString() avant son affichage.
La valeur du state nbr sera saisie par l'utilisateur, donc provient directement du composant TextInput:
<TextInput value={nbr.toString()}
style={{borderWidth:1, width:200, margin:10}}
keyboardType="numeric"
onChangeText={setNbr} />
Nous avons spécifié "numeric" pour l'attribut keyboardType afin que le clavier affiché suite à l'activation du champs soit numérique.

Vous avez probablement remarqué l'évènement onChangeText auquel on a associé le setter du state setNbr. En effet, en React Native, la récupération des valeurs des champs de saisie a été simplifiée. Il suffit de spécifier le nom du setter du state en guise d'event handler. L'argument qui est passé par défaut n'est rien d'autre que la valeur présente dans le champs.

En fin on spécifie notre useMemo comme ceci:
const carre = useMemo(()=>{
   console.log("Calcul du carré du nombre "+nbr)
   const nombre = parseInt(nbr)
   return isNaN(nombre)?"Aucun nombre spécifié":nombre**2
   },[nbr])
La variable à mémoriser a été identifiée par carre. Sa valeur est calculée par useMemo (ou plutôt par la fonction de callback passée en guise d'argument de useMemo).

L'instruction console.log("Calcul du carré du nombre "+nbr) est là pour identifier quand le calcul est exécuté. Souvenez-vous que l'objectif est d'éviter le calcul inutile d'une valeur qui en change pas. Donc le message qui sera affiché dans le console nous indiquera quand ce calcul a été réexécuté (évidement c'est suite au changement du state nbr).

La fonction de callback de useMemo retournera le résultat du calcul (le carré dans ce cas). Mais avant, il faut s'assurer si ce qui a été saisie est bel est bien un nombre. C'est pour cette raison qu'on a exprimé l'opérateur ternaire qui vérifie si le nombre n'est pas un NaN. Sinon on affiche "Aucun nombre spécifié".

Le deuxième argument de useMemo est un tableau qui contient le state nbr. Ce state constitue la dépendance qui une fois changée, useMemo est réexécutée et par conséquent la variable carre est recalculée.