OUJOOD.COM
Introduction
Le Hook `useRef` est utilisé pour deux objectifs principaux en React :
- Accéder directement aux éléments DOM : Permet de manipuler des éléments HTML sans passer par des méthodes comme `findDOMNode`.
- Conserver des valeurs mutables : Vous pouvez stocker des informations qui ne déclenchent pas de re-render lorsqu'elles sont modifiées.
Dans ce chapitre, nous allons explorer :
- Comment créer et utiliser une référence avec `useRef`.
- Des exemples pratiques pour illustrer ses fonctionnalités.
1. Qu'est-ce que `useRef` ?
`useRef` est un Hook React qui retourne un objet mutable contenant une propriété appelée `.current`. Cette propriété peut être utilisée pour :
- Stocker des références aux éléments DOM : Par exemple, pour mettre le focus sur un champ de saisie après un clic.
- Conserver des valeurs mutables : Utile pour stocker des données qui ne doivent pas déclencher de re-render lorsqu'elles changent.
Contrairement à `useState`, `useRef` ne provoque pas de mise à jour de l'interface utilisateur lorsque sa valeur change. Cela le rend parfait pour certaines situations où une mise à jour immédiate n'est pas nécessaire.
2. Utilisation de useRef
pour gérer le focus sur un champ input`
Voici un exemple simple où nous utilisons `useRef` pour mettre le focus automatiquement sur un champ de saisie lorsque l'utilisateur clique sur un bouton :
import React, { useRef } from 'react'; import { createRoot } from 'react-dom/client'; function FocusInput() { const inputRef = useRef(null); // Création d'une référence vers un élément DOM function handleClick() { inputRef.current.focus(); // Met le focus sur l'élément DOM lié à la référence } return ( <div> <input type="text" ref={inputRef} placeholder="Cliquez ici pour me sélectionner..." /> <button onClick={handleClick}>Mettre le focus</button> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<FocusInput />);
Explication détaillée ligne par ligne :
-
import React, { useRef } from 'react';
:- Nous importons React ainsi que le Hook
useRef
. useRef
permet de créer une référence mutable qui persiste tout au long du cycle de vie du composant.
- Nous importons React ainsi que le Hook
-
const inputRef = useRef(null);
:- Cette ligne crée une référence appelée
inputRef
, initialisée avecnull
. - La propriété
.current
de cette référence sera utilisée pour pointer vers l'élément DOM lié.
- Cette ligne crée une référence appelée
-
function handleClick() { ... }
:- Cette fonction est appelée lorsque l'utilisateur clique sur le bouton.
inputRef.current.focus()
: La méthodefocus()
est appelée sur l'élément DOM pointé parinputRef.current
, mettant ainsi le focus sur le champ de saisie.
-
<input type="text" ref={inputRef} />
:- Ce champ de saisie est lié à la référence
inputRef
via l'attributref
. - Lorsque le composant est monté,
inputRef.current
pointera vers l'élément DOM du champ de saisie.
- Ce champ de saisie est lié à la référence
-
<button onClick={handleClick}>Mettre le focus</button>
:- Ce bouton appelle la fonction
handleClick
lorsqu'il est cliqué. - Cela mettra le focus sur le champ de saisie associé à la référence
inputRef
.
- Ce bouton appelle la fonction
-
const root = createRoot(document.getElementById('root'));
:- Cette ligne crée une instance de racine React appelée
root
. document.getElementById('root')
spécifie l'élément HTML où le composant sera inséré.
- Cette ligne crée une instance de racine React appelée
-
root.render(<FocusInput />);
:- Rend le composant
FocusInput
dans l'élément HTML ayant l'idroot
. - Utilise
createRoot
pour garantir une compatibilité avec React 18 et versions ultérieures.
- Rend le composant
Pourquoi utiliser useRef
ici ?
useRef
permet d’accéder directement à un élément DOM sans provoquer de re-render du composant.- Contrairement à
useState
,useRef
ne déclenche pas de re-rendu lorsqu'il est mis à jour. - C'est utile pour des manipulations comme le focus, la lecture/écriture de valeurs DOM, ou encore l'intégration avec des bibliothèques tierces.
Améliorations possibles :
- Ajouter du style pour une meilleure expérience utilisateur.
- Gérer les cas où l’élément
inputRef.current
pourrait êtrenull
. - Ajouter un message dynamique lorsque l'input reçoit le focus.
Version améliorée avec gestion d'état :
Si vous voulez informer l'utilisateur quand l'input a le focus :
import React, { useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; function FocusInput() { const inputRef = useRef(null); const [message, setMessage] = useState(""); function handleClick() { inputRef.current.focus(); setMessage("L'input est sélectionné !"); } return ( <div> <input type="text" ref={inputRef} placeholder="Cliquez ici pour me sélectionner..." onBlur={() => setMessage("")} // Réinitialisation du message quand l'input perd le focus /> <button onClick={handleClick}>Mettre le focus</button> <p>{message}</p> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<FocusInput />);
Cela rend l'expérience utilisateur plus interactive en affichant un message lorsque l'input est sélectionné. 🚀
3. Conservation de Valeurs Mutables avec `useRef`
En plus de manipuler des éléments DOM, `useRef` peut être utilisé pour conserver des valeurs mutables entre les re-renders sans déclencher de mise à jour de l'interface utilisateur. Voici un exemple où nous conservons un compteur dans une référence :
import React, { useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; function Compteur() { const [compte, setCompte] = useState(0); // Gestion de l'état affiché const compteurRef = useRef(0); // Référence pour conserver une valeur mutable function incrementer() { compteurRef.current += 1; // Incrémente la valeur de la référence setCompte(compteurRef.current); // Met à jour l'état affiché avec la valeur actuelle de la référence } return ( <div> <p>Vous avez cliqué {compte} fois.</p> <button onClick={incrementer}>Incrémenter</button> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<Compteur />);
Explication détaillée ligne par ligne :
-
const compteurRef = useRef(0);
:- Cette ligne crée une référence appelée
compteurRef
, initialisée avec la valeur0
. - La propriété
.current
de cette référence peut être modifiée sans déclencher de re-render du composant.
- Cette ligne crée une référence appelée
-
compteurRef.current += 1;
:- Cette ligne incrémente la valeur de la référence
compteurRef.current
de1
. - Contrairement à `useState`, cette modification ne provoque pas de mise à jour immédiate de l'interface utilisateur.
- Cette ligne incrémente la valeur de la référence
-
setCompte(compteurRef.current);
:- Cette ligne met à jour l'état affiché (
compte
) avec la valeur actuelle de la référencecompteurRef.current
. - Seule cette mise à jour de l'état déclenche un re-render du composant.
- Cette ligne met à jour l'état affiché (
-
<button onClick={incrementer}>Incrémenter</button>
:- Ce bouton appelle la fonction
incrementer
lorsqu'il est cliqué. - Cela incrémente la valeur de la référence
compteurRef
et met à jour l'état affiché.
- Ce bouton appelle la fonction
Pourquoi utiliser useRef
ici ?
- Permet de stocker une valeur mutable sans déclencher un re-render.
- Améliore les performances en évitant des mises à jour inutiles.
Version améliorée avec réinitialisation :
import React, { useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; function Compteur() { const [compte, setCompte] = useState(0); const compteurRef = useRef(0); function incrementer() { compteurRef.current += 1; setCompte(compteurRef.current); } function reinitialiser() { compteurRef.current = 0; setCompte(0); } return ( <div> <p>Vous avez cliqué {compte} fois.</p> <button onClick={incrementer}>Incrémenter</button> <button onClick={reinitialiser}>Réinitialiser</button> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<Compteur />);
Ce composant permet d'incrémenter un compteur et de le réinitialiser en utilisant useRef
et useState
. 🚀
4. Comparaison entre `useState` et `useRef`
Bien qu'ils puissent sembler similaires, `useState` et `useRef` ont des usages distincts. Voici leurs différences principales :
Aspect | useState | useRef |
---|---|---|
Fonctionnement | Déclenche un re-render lorsque sa valeur change. | Ne déclenche pas de re-render lorsque sa valeur change. |
Utilisation | Utilisé pour gérer des états qui affectent l'interface utilisateur. | Utilisé pour conserver des valeurs mutables ou accéder directement aux éléments DOM. |
Exemple Typique | Gestion d'un compteur affiché sur l'écran. | Mise au focus d'un champ de saisie ou stockage d'une valeur temporaire. |
5. Exemple Pratique : Compteur avec Conservation de Valeurs
Imaginons que vous souhaitez créer un compteur qui conserve son ancienne valeur même après un re-render. Voici comment cela peut être fait :
import React, { useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; function CompteurPersistant() { const [compte, setCompte] = useState(0); // État affiché const dernierCompteRef = useRef(0); // Référence pour conserver la dernière valeur function incrementer() { setCompte(compte + 1); // Met à jour l'état affiché dernierCompteRef.current = compte; // Conserve la dernière valeur dans la référence } return ( <div> <p>Vous avez cliqué {compte} fois.</p> <p>Dernière valeur avant l'incrément : {dernierCompteRef.current}</p> <button onClick={incrementer}>Incrémenter</button> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<CompteurPersistant />);
Explication détaillée ligne par ligne :
-
const dernierCompteRef = useRef(0);
:- Cette ligne crée une référence appelée
dernierCompteRef
, initialisée avec la valeur0
. - Elle servira à conserver la dernière valeur du compteur avant chaque incrément.
- Cette ligne crée une référence appelée
-
dernierCompteRef.current = compte;
:- Cette ligne met à jour la propriété
.current
de la référencedernierCompteRef
avec la valeur actuelle decompte
. - Cette mise à jour ne déclenche pas de re-render, car
useRef
est conçu pour conserver des valeurs mutables.
- Cette ligne met à jour la propriété
-
<p>Dernière valeur avant l'incrément : {dernierCompteRef.current}</p>
:- Cet élément affiche dynamiquement la valeur conservée dans la référence
dernierCompteRef.current
.
- Cet élément affiche dynamiquement la valeur conservée dans la référence
Conclusion
Vous avez maintenant appris à utiliser le Hook `useRef` pour deux objectifs principaux : accéder directement aux éléments DOM et conserver des valeurs mutables sans déclencher de re-render. Ces fonctionnalités rendent `useRef` particulièrement utile dans des scénarios où une interaction directe avec le DOM ou la persistance de valeurs est requise.
Prochain chapitre : useReducer