DEV Community

Cover image for Como utilizar o Intersection Observer no React
Henrique Rodrigues
Henrique Rodrigues

Posted on

Como utilizar o Intersection Observer no React

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.

limite explicado

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)
Enter fullscreen mode Exit fullscreen mode

O object construtor do intersection observer necessita de dois argumentos:

  1. Uma função de callback
  2. 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
}
Enter fullscreen mode Exit fullscreen mode
  • 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

gif de implementação da janela de visualização

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>
)

Enter fullscreen mode Exit fullscreen mode
  1. Comece por uma referência ao elemento que queremos observar, utilize o react hook useRef.
  2. 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.
  3. 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).
  4. Crie o objeto de opções com os mesmos valores da imagem.
  5. 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.
  6. Defina a variável useRef no elemento que queremos observar.
<div className="box" ref={containerRef}>Observe me</div>
Enter fullscreen mode Exit fullscreen mode
  1. Vamos adicionar um pouco de estilo nesse html.

css

  1. Isso é tudo que precisamos, simples e fácil!

Relembrando, isso é apenas uma implementação básica e existe diversas maneiras de fazer isso.

Resultado final


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]

}

Enter fullscreen mode Exit fullscreen mode
  1. Crie uma nova função chamada useElementOnScreen com as opções de parâmetros
  2. Mover o useRef, useState e useEffect inteiro dentro do nosso novo hook.
  3. Agora, a única coisa que falta no nosso gancho é a instrução return, passamos isVisible e containerRef como um array.
  4. 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>
)
Enter fullscreen mode Exit fullscreen mode

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 (0)