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. useRefpermet 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é
.currentde 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
inputRefvia l'attributref. - Lorsque le composant est monté,
inputRef.currentpointera 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
handleClicklorsqu'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
FocusInputdans l'élément HTML ayant l'idroot. - Utilise
createRootpour garantir une compatibilité avec React 18 et versions ultérieures.
- Rend le composant
Pourquoi utiliser useRef ici ?
useRefpermet d’accéder directement à un élément DOM sans provoquer de re-render du composant.- Contrairement à
useState,useRefne 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.currentpourrait ê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é
.currentde 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.currentde1. - 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
incrementerlorsqu'il est cliqué. - Cela incrémente la valeur de la référence
compteurRefet 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é
.currentde la référencedernierCompteRefavec la valeur actuelle decompte. - Cette mise à jour ne déclenche pas de re-render, car
useRefest 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