kevin nkonda

Un hook pour détecter la largeur de l'écran

2019-11-24reacthookgatsby

Comment détecter la largeur de l’écran avec React ?

J’ai eu récemmment besoin de désactiver un effet de parallax lorsque la largeur de l’écran passe en-dessous de 1200px. Quelques recherches sur Google et quelques clics plus tard, je suis tombé sur ce site très intéressant : usehooks.com. Ce site donne des exemples simples à comprendre, mais concrets, de l’utilisation qu’on peut faire des hooks. Je t’invite à y faire un tour et à en tester quelques-uns !

Pour l’instant, si t’as pas le temps (ou la flemme) d’aller voir, je te mets ici le snippet en question :

import { useState, useEffect } from "react";

// Hook
function useWindowSize() {
  const isClient = typeof window === "object";

  function getSize() {
    return {
      width: isClient ? window.innerWidth : undefined,
      height: isClient ? window.innerHeight : undefined
    };
  }

  const [windowSize, setWindowSize] = useState(getSize);

  useEffect(() => {
    if (!isClient) {
      return false;
    }

    function handleResize() {
      setWindowSize(getSize());
    }

    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []); // Empty array ensures that effect is only run on mount and unmount

  return windowSize;
}

Mais ça fait quoi concrètement ?

On détecte d’abord si on est côté client ou côté serveur :

const isClient = typeof window === "object";`

Puis on définit la fonction getSize, qui retournera un objet contenant la hauteur et la largeur de la fenêtre : si l’application est chargée dans le navigateur, les valeurs correspondront à la largeur et la hauteur de la fenêtre ; sinon, elles seront égales à undefined :

function getSize() {
  return {
    width: isClient ? window.innerWidth : undefined,
    height: isClient ? window.innerHeight : undefined
  };
}

Ensuite, on définit la variable d’état windowSize et la fonction pour la modifier setWindowSize, via un hook d’état :

const [windowSize, setWindowSize] = useState(getSize);

Le hook d’effet qui suit va d’abord s’assurer que nous sommes bien côté client, et va attacher un eventListener à la fenêtre qui va faire appel à la fonction handleResize à chaque changement de taille de la fenêtre :

if (!isClient) {
      return false;
    }

[...]

window.addEventListener("resize", handleResize);

Cette fonction quant à elle mettra à jour la largeur de l’écran en faisant appel à getSize().

function handleResize() {
  setWindowSize(getSize());
}

Enfin, c’est l’objet windowSize qui sera retourné par le hook useWindowSize, et que l’on va exploiter par la suite :

return windowSize;

Comment utiliser ce hook ?

Tout d’abord, il faut bien évidemment l’importer (sauf bien sûr si tu le mets dans le même fichier, dans ce cas tu n’as pas besoin de le faire…) : Smart

import useScreenSize from "../hooks/useScreenSize";

Et ensuite tu accèdes à la valeur ‘width’ comme ceci :

const screenWidth = useScreenSize().width;

Pour finir, utilise un hook d’effet pour que la valeur soit mise à jour en temps réel :

const [disableParallax, setdisableParallax] = useState(false);

useEffect(() => {
  if (screenWidth <= 1200) {
    setdisableParallax(true);
  } else {
    setdisableParallax(false);
  }
}, [screenWidth]);

Si tu n’es pas familier avec les hooks, voilà ce qui se passe : la valeur de la variable d’état disableParallax change lorsque la largeur de la fenêtre franchit 1200px, grâce à la fonction setdisableParallax, qui est l’équivalent de setState dans un composant à base de classes.

Voilà ! J’espère que cette explication te sera utile, laisse un commentaire si le coeur t’en dis 👇