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 7: Le hook useRef pour créer une référence à un composant

Toutes les pages

Le hook useRef

Créer une référence mutable à un composant React Native

En React Native (comme en React web), le hook useRef permet de créer une sorte de boîte mémoire qui conserve une valeur entre les rendus du composant, sans provoquer de re-rendering lorsqu’on la modifie. Cette référence est dite mutable car on peut changer son contenu à tout moment. En plus, elle est persistante car elle ne se réinitialise pas à chaque affichage du composant.

Le hook useRef crée une référence qu'on utilise souvent pour accéder à un élément natif (comme un champ TextInput pour déclencher un focus), stocker des valeurs intermédiaires (comme un compteur ou un timer) ou garder en mémoire une valeur précédente sans impacter l’interface. C’est un outil discret mais puissant pour gérer des états invisibles un peu comme un carnet de notes que le composant garde dans sa poche entre chaque exécution.

L'attribut current généré par useRef

Quand on utilise useRef en React Native, on obtient un objet de la forme { current: ... }. Cet objet est retourné une seule fois lors du premier rendu et sa propriété current est celle qu’on peut librement lire ou modifier sans que cela déclenche un re-render du composant.

On peut donc imaginer ceci comme si React nous donnait une boîte nommée ref (comme on va le voir dans l'exemple), et cette boîte contient un seul tiroir appelé current dans lequel on peut ranger ce qiu'on veut (une valeur, une référence à un composant natif, ou même une fonction). Ce tiroir reste accessible et inchangé entre les rendus, ce qui en fait un excellent outil pour stocker des données temporaires ou interagir avec l’interface sans perturber le cycle de rendu.

Exemple d'utilisation de useRef

Dans cet exemple, nous allons intégrer une zone de texte et un bouton à notre vue. L'objectif consiste à déclencher le focus sur la zone de texte une fois le bouton cliqué. Nous allons cette fois invoquer le composant <TextInput> qui représente un champ de saisie similaire à une zone de texte classique en HTML.

Le code complet ressemblera à ceci:
import { useRef } from 'react';
import { StyleSheet, TextInput, Button, View } from 'react-native';

export default function App() {
   const inputRef = useRef(null);

   const handleFocus = () => {
      inputRef.current?.focus();
   };

   return (
      <View style={styles.container}>
         <TextInput
         ref={inputRef}
         placeholder="Champ à saisir"
         style={{ borderWidth: 1, padding:
         10, width: 200 }}
         />
         <Button title="Focus sur le champ"
         onPress={handleFocus} />
      </View>
   );
}

const styles = StyleSheet.create({
   container: {
      flex: 1,
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
   },
});
Pour le moment, nous n'allons pas nous arrêter sur les styles appliqués. On aura l'occasion de détailler cette rubrique plus loin dans ce cours.
Après exécution on obtient ce résultat:
Passons à l'explication:

La première opération consiste à importer le module useRef:
import { useRef } from 'react';
Comme expliqué auparavant, cette importation sera automatiquement ajoutée par l'IDE quand il aura détecté l'utilisation du hook useRef dans le code.

Ensuite, on crée une référence persistante à un élément ou une valeur dans un composant React Native à l'aide de l'instruction suivante:
const inputRef = useRef(null);
On spécifie l'élément qui utilisera la référence que l'on vient de créer à l'aide du mot-clé ref (similaire à un attribut HTML). Dans ce cas le composant <TextInput>:
<TextInput
ref={inputRef}
placeholder="Champ à saisir"
style={{ borderWidth: 1, padding: 10, width: 200 }}
/>
Quant à la fonction qui sera exécutée une fois on clique sur le bouton et qui se chargera de donner le focus à la zone de texte, elle ressemblera à ceci:
const handleFocus = () => {
   inputRef.current?.focus();
};
Vous avez remarqué l'attribut current qui fait partie de l'objet créé automatiquement par useRef. Pour faire simple, on peut imaginer inputRef.input comme event.target ou event.currentTarget que l'on utilise dans une application Web.

Le point d'interrogation placé après current dans inputRef.current?.focus() sert de mesure de sécurité lors de l'accès à un élément natif. On l'appelle optional chaining et il vérifie que current n’est pas null ou undefined avant d’appeler .focus().

Donc le code
inputRef.current?.focus();
est équivalent à
if (inputRef.current) {
   inputRef.current.focus();
}
L’optional chaining (?.) en JavaScript offre un avantage majeur. En effet, il permet d’accéder à des propriétés ou des méthodes sans provoquer d’erreur si une partie de la chaîne est null ou undefined. En plus, il rend le code plus concis et lisible.