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:
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.