Chargement…

Un hook React pour gérer le Dark Mode

Un hook React pour gérer le Dark Mode

Je vous ai dit, je suis un grand fanatique des hooks, leur réutilisabilité, leur accès au lifecycle etc font d'eux un atout fondamental de React.

Aujourd'hui on va parler du Dark Mode et du Light Mode. N'ayant pas besoin de présenter davantage le sujet, je vous propose de passer immédiatement à la pratique.

On va directement créer un hook qui renverra un booléen isDarkMode dès que le thème d'affichage change. Il s'agira d'un state donc, cela va redéclencher le render de vos composants.

// /hooks/useTheme.tsx

import React from "react";

export const useTheme = () => {
  const [isDarkMode, setIsDarkMode] = React.useState(false);

  React.useEffect(() => {
    if (
      window.matchMedia &&
      window.matchMedia("(prefers-color-scheme: dark)").matches
    ) {
      setIsDarkMode(true);
    }

    const listener = (event: MediaQueryListEvent) => {
      const newColorScheme = event.matches ? "dark" : "light";
      setIsDarkMode(newColorScheme === "dark");
    };

    window
      .matchMedia("(prefers-color-scheme: dark)")
      .addEventListener("change", listener);

    // Cleanup
    return () => {
      window
        .matchMedia("(prefers-color-scheme: dark)")
        .removeEventListener("change", listener);
    };
  }, []);

  return { isDarkMode };
};

Ensuite nous pouvons l'utiliser dans n'importe quel composant en une simple ligne:

const { isDarkMode } = useTheme();

Et avec ce hook des plus rudimentaire, nous obtenons ceci :

dark_mode.gif

Dans cet exemple, je remplace le logo de la navbar en fonction du thème pour passer du noir au blanc.

🎉🎉 Victoire ! 😊

FAQ

Le hook détecte-t-il le thème au chargement de la page ou seulement lors d'un changement ?

Les deux. Au montage du composant, il vérifie immédiatement la préférence système via window.matchMedia, puis il écoute les changements en temps réel grâce à un event listener.

Que se passe-t-il si l'utilisateur change son thème système pendant qu'il navigue sur le site ?

Le hook réagit instantanément grâce à l'écouteur d'événement sur prefers-color-scheme. Le state isDarkMode est mis à jour, ce qui redéclenche le render des composants qui utilisent ce hook.

Est-ce qu'il faut nettoyer quelque chose pour éviter des fuites mémoire ?

Oui, et c'est déjà géré dans le hook. La fonction de cleanup retournée par useEffect retire l'event listener dès que le composant est démonté.

Ce hook fonctionne-t-il dans un projet Next.js avec le rendu côté serveur ?

Pas directement, car window n'est pas disponible côté serveur. Il faudrait ajouter une vérification du type typeof window !== 'undefined' avant d'appeler window.matchMedia.

Peut-on utiliser ce hook dans plusieurs composants en même temps ?

Oui, c'est justement l'intérêt d'un hook React. Chaque composant qui appelle useTheme aura son propre state, mais tous réagiront aux mêmes changements système.


Poursuivre la lecture

Organiser efficacement ses requêtes React-Query Dev
#react#react-query#hook

Organiser efficacement ses requêtes React-Query

Tous les projets React ne sont pas égaux en matière d'organisation des requêtes. J'aime bien que les dossiers ne soient pas un labyrinthe et que l'on sache exactement quoi faire pour répliquer l'existant sans créer de doublons. Voici comment je procède.

Alexandre P.
Comment formater son texte sur des composants React Dev
#react#text#library

Comment formater son texte sur des composants React

Apprenez à formater proprement vos templates string en React et améliorer la lisibilité de vos composants frontend.

Alexandre P.