Comment faire un composant ScrollToTop avec React
React Typescript TailwindIntroduction
Dans cet article nous allons découvrir comment réaliser un composant ScrollToTop
, afin de remonter en haut d’une page Web, de manière smooth.
Pour ce faire, nous utiliserons la méthode window.scrollTo()
supportée dans la plupart des navigateurs.
La méthode scrollTo
accepte en entrée un objet contenant des coordonnées left
& right
, ainsi qu’un champ behavior
définissant le comportement du scroll :
window.scrollTo({ top: 0, left: 0, behavior: "smooth" });
Le composant IconArrowTop
Commençons par créer un composant IconArrowTop
qui hébergera un icône pour la flêche du ScrollToTop
:
// src/components/icons/IconArrowTop.tsx
impor { FunctionComponent } from "react";
const IconArrowTop: FunctionComponent = () => {
return (
<svg
className="h-8 w-8"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 26 26"
stroke="currentColor"
strokeWidth="2"
>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 15l7-7 7 7" />
</svg>
);
};
export default IconArrowTop;
Rien de bien particulier ici, il s’agit d’un functional component
qui renvoie un svg. Nous utilisons également les classes Tailwind w-8
et h-8
pour fixer une taille par défaut, à l’icône.
Le composant ScrollToTop
Nous allons par la suite, créer notre composant ScrollToTop
, pour l’instant il renverra uniquement le composant IconArrowTop
:
// src/components/ui/ScrollToTop.tsx
import { FunctionComponent } from "react";
import ArrowTopIcon from "../icons/IconArrowTop";
const ScrollToTop: FunctionComponent = () => {
return <ArrowTopIcon />;
};
export default ScrollToTop;
Passons ensuite, à la partie plus intéressante, nous souhaitons cacher le ScrollToTop
à partir d’un certain offset
de l’axe Y. Cela permettra à l’utilisateur de voir le composant à partir du moment ou il aura assez scrollé vers le bas.
// src/components/ui/ScrollToTop.tsx
import { FunctionComponent, useEffect, useState } from "react";
import ArrowTopIcon from "../icons/IconArrowTop";
const minYOffset = 400;
const ScrollToTop: FunctionComponent = () => {
const [scrollY, setScrollY] = useState(0);
const checkScrollTop = () => setScrollY(window.pageYOffset);
return (
<div
className={`${
scrollY > minYOffset ? "flex" : "hidden"
} z-20 fixed bottom-6 right-6 md:bottom-20 md:right-20 cursor-pointer animate-bounce bg-white p-2 w-16 h-16 border border-gray-200 text-secondary shadow-lg rounded-full items-center justify-center`}
>
<ArrowTopIcon />
</div>
);
};
export default ScrollToTop;
La méthode checkScrollTop
permettra de setter la valeur courante du scroll.
Vous remarquerez que nous avons aussi ajouter une condition sur les classes css Tailwind (flex
/ hidden
) du composant afin d’afficher ou cacher l’élément selon la position du scroll de l’utilisateur. Si le scroll est supérieur à 400px, l’élément apparaîtra.
Il ne nous reste plus qu’à détecter la position du scroll de l’utilisateur à l’aide du hook useEffect
et d’utiliser la méthode window.scrollTo()
fournie par le navigateur :
// src/components/ui/ScrollToTop.tsx
import { FunctionComponent, useCallback, useEffect, useState } from "react";
import ArrowTopIcon from "../icons/IconArrowTop";
const minYOffset = 400;
const ScrollToTop: FunctionComponent = () => {
const [scrollY, setScrollY] = useState(0);
const checkScrollTop = useCallback(
() => setScrollY(window.pageYOffset),
[setScrollY]
);
useEffect(() => {
window.addEventListener("scroll", checkScrollTop);
return () => window.removeEventListener("scroll", checkScrollTop);
}, [checkScrollTop]);
const scrollTop = () => window.scrollTo({ top: 0, behavior: "smooth" });
return (
<div
className={`${
scrollY > minYOffset ? "flex" : "hidden"
} z-20 fixed bottom-6 right-6 md:bottom-20 md:right-20 cursor-pointer animate-bounce bg-white p-2 w-16 h-16 border border-gray-200 text-secondary shadow-lg rounded-full items-center justify-center`}
onClick={scrollTop}
>
<ArrowTopIcon />
</div>
);
};
export default ScrollToTop;
Nous avons également utiliser le hook useCallback
afin de s’assurer que la fonction checkScrollToTop garde la même référence et ne re-déclenche pas le code situé dans le hook useEffect
.
Une fonction de nettoyage est également retournée dans l’appel du useEffect
, cela permet de proprement retirer le listener dans le cas où le composant est détruit ou est ré-évalué après un rendering.
Pour finir, l’évènement onClick
a été utilisé sur la div
parente du ScrollToTop
. La méthode scrollTop
étant connectée à ce listener.