Esse hook te permite facilmente detectar quando um elemento é visível na tela e também especificar o quanto do elemento deve estar visível antes de ser considerado dentro da tela. Perfeito para Lazy loading de imagens ou ativar animações quando o usuário desce para uma determinada seção.
import { useState, useEffect, useRef } from "react"; // Uso function App() { // Referência para o elemento que nós queremos detectar se está em tela const ref = useRef(); // Chamamos o hook passando a referência e o margin de root // Neste caso, ele seria considerado em tela se mais ... // ... que 300px do elemento estiver visível. const onScreen = useOnScreen(ref, "-300px"); return ( <div> <div style={{ height: "100vh" }}> <h1>Descer para a próxima sessão...</h1> </div> <div ref={ref} style={{ height: "100vh", backgroundColor: onScreen ? "#23cebd" : "#efefef", }} > {onScreen ? ( <div> <h1>Hey Eu estou na tela</h1> <img src="https://i.giphy.com/media/ASd0Ukj0y3qMM/giphy.gif" /> </div> ) : ( <h1>Descer mais 300px do topo dessa sessão</h1> )} </div> </div> ); } // Hook function useOnScreen(ref, rootMargin = "0px") { // Estado e setter para armazenar se o elemento está visível const [isIntersecting, setIntersecting] = useState(false); useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { // Atualizar o estado quando o callback do observador dispara setIntersecting(entry.isIntersecting); }, { rootMargin, } ); if (ref.current) { observer.observe(ref.current); } return () => { observer.unobserve(ref.current); }; }, []); // Array vazio que garante que o efeito é executado apenas na montagem e desmontagem return isIntersecting; }
Criado por @guilherssousa, mantido por 1 pessoas 💗