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.