Simplifiez les accès du DOM grâce à la fonction d'initialisation ref (React)
ReactIntroduction
Découvrez une manière plus efficace et élégante de manipuler le DOM dans vos projets React !
Dans cet article, je vous montre comment utiliser la fonction d’initialisation ref
, une alternative puissante à useEffect
pour interagir directement avec les éléments du DOM.
🎯 Ce que vous allez apprendre
- Comment utiliser
useEffect
etuseRef
pour manipuler le DOM (méthode classique). - Les limitations de cette approche et pourquoi elle n’est pas toujours optimale.
- La puissance de la fonction
ref
pour simplifier et optimiser votre code. - Un cas pratique : injection d’un script dans un élément DOM.
📚 Exemple de code
Approche classique avec useEffect
"use client";
import { useEffect, useRef } from "react";
const DomManipulationDemo = () => {
const divRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const element = divRef.current;
if (element) {
element.classList.add("bg-blue-100");
element.textContent = "Text updated with useEffect()";
}
}, []);
return (
<div ref={divRef} className="p-5 border border-black">
Initial Content
</div>
);
};
export default DomManipulationDemo;
Dans cet exemple, nous utilisons useRef
pour référencer un élément DOM, puis useEffect
pour modifier son style et son contenu.
J’ajoute également classe Tailwind pour modifier la couleur d’arrière-plan et je mets également à jour le contenu du nœud.
Étant donné que le tableau de dépendances du useEffect est vide, le code ne s’exécute qu’une seule fois, lorsque le composant est monté.
Il s’agit d’une approche fonctionnelle, mais elle nécessite d’utiliser à la fois useRef et useEffect.
Il existe un moyen plus simple de procéder : la fonction d’initialisation ref.
Approche moderne avec la fonction ref
Alors, comment fonctionne cette fonction d’initialisation ?
Cette fonction reçoit l’élément DOM que vous souhaitez manipuler en tant que paramètre, et elle est appelée lors du montage du composant.
"use client";
import { useCallback } from "react";
const DomManipulationDemo = () => {
const setupRef = useCallback((element: HTMLDivElement) => {
if (element) {
element.classList.add("bg-green-200");
element.textContent = "Text added with setup ref";
}
}, []);
return (
<div ref={setupRef} className="p-5 border border-black">
Initial Content
</div>
);
};
export default DomManipulationDemo;
L’avantage principal de cette fonction est que vous évitez complètement le cycle de vie lié à useEffect
.
Le code est plus direct puisque vous n’avez pas besoin d’un effet de bord pour manipuler le DOM.
Et ici, j’utilise useCallback
pour préserver la référence à la fonction setup et éviter les rendus répétés.
Le code à l’intérieur de la fonction est identique à l’exemple précédent
Et enfin, la fonction setup
est passée en paramètre à l’attribut ref
.
De plus, useRef
n’est plus nécessaire.
💡 Pourquoi utiliser la fonction ref ?
- Plus simple : Pas besoin d’un effet secondaire comme avec
useEffect
. - Plus performant : Accès direct à l’élément DOM dès qu’il est monté.
- Moins de dépendances : Pas besoin de
useRef
ni de tableau de dépendances.
🛠 Cas pratique : Injection d’un script
Voici un autre exemple pratique : imaginez que vous ayez besoin d’injecter un script JavaScript dans un div.
Avec la fonction d’initialisation ref, c’est un jeu d’enfant :
"use client";
import { useCallback } from "react";
declare global {
interface Window {
updateText?: () => void;
}
}
const SCRIPT_ID = "demo-script";
const ScriptInjectionDemo = () => {
const setupRef = useCallback((element: HTMLDivElement) => {
if (!window.updateText && element) {
const script = document.createElement("script");
script.id = SCRIPT_ID;
script.src = "/demo-script.js";
element.appendChild(script);
}
setTimeout(() => window.updateText?.(), 100);
}, []);
return (
<div
id="script-injection-demo"
ref={setupRef}
className="p-5 border border-black"
/>
);
};
export default ScriptInjectionDemo;
Ici, j’injecte un script directement dans le DOM, seulement s’il n’a pas déjà été injecté.
L’appel setTimeout
est un peu un hack car j’attache une fonction à l’objet window
.
Il me permet d’attendre que le script se charge avant de l’appeler.
Vous n’aurez généralement pas besoin d’utiliser setTimeout
; c’est juste à des fins de démonstration.
Voici à quoi ressemble le script injecté :
function updateText() {
const element = document.getElementById("script-injection-demo");
if (element) {
element.classList.add("bg-blue-100");
element.textContent = "Text updated with script injection";
}
}
window.updateText = updateText;
Je déclare une fonction updateText
pour mettre à jour le contenu du nœud, comme précédemment.
J’attache cette fonction à l’objet window
.
Simple et efficace !
📣 Donnez-moi votre avis !
Que pensez-vous de cette méthode ?
Utilisez-vous déjà la fonction ref dans vos projets ? Dites-le-moi en commentaire ou sur les réseaux sociaux ! 👍