Hoje vamos explorar como utilizar a API do intersection observer no React com alguns exemplos.
Mozilla web documentation descreve a API intersection observer como:
permite que o código registe uma função de chamada de retorno que é executada sempre que um elemento que desejam monitorizar entra ou sai de outro elemento (ou da janela de visualização), ou quando o valor pelo qual os dois se cruzam muda de um valor solicitado. Desta forma, os sites já não precisam de fazer nada no thread principal para observar este tipo de interseção de elementos, e o browser fica livre para otimizar a gestão das interseções como achar melhor.
Resumindo, permite-nos detectar quando certo elemento está visível no viewport, isto só acontece quando o elemento cumpre a proporção de interseção desejada.
Como você pode ver, se fazer um scroll dow na pagina o intersection ratio aumentará até atingir o limite projetado e nesse momento é acionada a função que executa uma chamada de retorno.
Primeiro passo
const observer = new IntersectionObserver(callbackFunction, options)
observer.observer(elementToObserver)
O object construtor do intersection observer necessita de dois argumentos:
- Uma função de callback
- Opções
Apenas isso, estamos pronto para ver alguma ação, mais primeiro, precisamos saber o que cada opção significa, o argumento options é um objecto com os seguinte valores:
const options = {
root: null,
rootMargin: "0px",
threshold: 1
}
- root: O elemento que é utilizado como viewport para verificar a visibilidade do alvo. Deve ser o antepassado do alvo. O predefinido é a janela de visualização do browser se não for especificado ou se for nulo.
- rootMargin: Este conjunto de valores serve para aumentar ou diminuir cada lado da caixa delimitadora do elemento raiz antes de calcular as intersecções, as opções são semelhantes às da margem em CSS.
- limite: Um único número ou uma matriz de números que indica em que percentagem da visibilidade do alvo o retorno de chamada do observador deve ser executado, varia de 0 a 1,0, em que 1,0 significa que cada pixel está visível na janela de visualização.
Utilizando no React
Agora vamos ver uma implementação da API do intersection observer no React.
const containerRef = useRef(null)
const [isVisible, setIsVisible] = useState(false)
const callbackFunction = (entries) => {
const [entry] = entries
setIsVisible(entry.isIntersecting)
}
const options = {
root: null,
rootMargin: "0px",
threshold: 1.0
}
useEffect(() => {
const observer = new IntersectionObserver(callbackFunction, options)
if (containerRef.current) observer.observe(containerRef.current)
return () => {
if (containerRef.current) observer.unobserve(containerRef.current)
}
}, [containerRef, options])
return (
<div className="app">
<div className="isVisible">{isVisible ? "IN VIEWPORT" : "NOT IN VIEWPORT"}</div>
<div className="section"></div>
<div className="box" ref={containerRef}>Observe me</div>
</div>
)
- Comece por uma referência ao elemento que queremos observar, utilize o react hook useRef.
- Crie uma variável de estado isVisible, vamos utilizá-la para apresentar uma mensagem sempre que a nossa caixa estiver na janela de visualização.
- Declare a callback function que vai receber um array de IntersectionObserverEntries como parâmetro, dentro desta função pegamos na primeira e única entrada e verificamos se está a cruzar com a viewport e se estiver então chamamos setIsVisible com o valor do entry.isIntersecting (true/ FALSO).
- Crie o objeto de opções com os mesmos valores da imagem.
- Adicione o react hook useEffect e crie um construtor observador utilizando a callback function e as opções que acabámos de criar antes. É opcional no nosso caso, mas pode devolver uma função de limpeza para desobservar o nosso alvo quando o componente é desmontado.
- Defina a variável useRef no elemento que queremos observar.
<div className="box" ref={containerRef}>Observe me</div>
- Vamos adicionar um pouco de estilo nesse html.
- Isso é tudo que precisamos, simples e fácil!
Relembrando, isso é apenas uma implementação básica e existe diversas maneiras de fazer isso.
Vamos agora implementar o mesmo código que fizemos anteriormente, mas separando toda a lógica nu hook chamado useElementOnScreen.
const useElementOnScreen = (options) => {
const containerRef = useRef(null)
const [isVisible, setIsVisible] = useState(false)
const callbackFunction = (entries) => {
const [entry] = entries
setIsVisible(entry.isIntersecting)
}
useEffect(() => {
const observer = new IntersectionObserver(callbackFunction, options)
if (containerRef.current) observer.observe(containerRef.current)
return () => {
if (containerRef.current) observer.unobserve(containerRef.current)
}
}, [containerRef, options])
return [containerRef, isVisible]
}
- Crie uma nova função chamada useElementOnScreen com as opções de parâmetros
- Mover o useRef, useState e useEffect inteiro dentro do nosso novo hook.
- Agora, a única coisa que falta no nosso gancho é a instrução return, passamos
isVisible
econtainerRef
como um array. - ok, estamos quase lá, só precisamos de chamar no nosso componente e ver se funciona!
const [containerRef, isVisible] = useElementOnScreen({
root: null,
rootMargin: "0px",
threshold: 1.0
})
return (
<div className="app">
<div className="isVisible">{isVisible ? "IN VIEWPORT" : "NOT IN VIEWPORT"}</div>
<div className="section"></div>
<div className="box" ref={containerRef}>Observe me</div>
</div>
)
1- Importe o hook criado recentemente para o nosso componente.
2 - Inicialize-o com o objeto de opções.
3 - Assim terminamos.
Parabéns, utilizámos com sucesso a API intersection observer e até criámos um gancho para a mesma!
Créditos
Intersection Observer using React, escrito originalmente por producthackers
Obrigado por ler este artigo. Espero poder fornecer-lhes algumas informações úteis. Se sim, eu ficaria muito feliz se você recomendasse este post e clicasse no botão do ♥ para que mais pessoas possam ver isso.
Top comments (1)
Thanks for sharing! I’d like to mention that using EchoAPI with my React applications has streamlined my API testing, ensuring smooth integration with my components.