Imagine se deparar com o seguinte problema: Você deve carregar uma imagem para o usuário somente quando ele ver o componente na tela. Uma das coisas mais complexas no desenvolvimento web é saber exatamente quando um elemento aparece pelo usuário.
Primeiramente pensei em fazer cálculos com o scroll event, porém isso poderia facilmente trazer problemas de performance para a aplicação. Então, fiz como todo bom desenvolvedor, passei horas pesquisando possíveis soluções e encontrei uma de implementação bem simples, sem necessidade de trazer libs para o projeto, o Intersection Observer API.
Como o Intersection Observer API funciona ?
O Intersection Observer API é uma API do browser, de forma resumida, ela observa um elemento alvo e informa quando há a interseção desse elemento alvo com um outro elemento ou o com viewport. Em outras palavras, com essa API é possível saber quando o elemento aparece para o usuário. Para mais detalhes da API aqui está a documentação dela.
Essa API espera dois parâmetros, um callback e um objeto, com as opções para a API observar o elemento. Essas opções são o root, rootMargin e threshold.
root: O elemento que é utilizado como viewport para o elemento alvo, se passado root com “null” o próprio viewport é utilizado.
rootMargin: Margin em volta do root. Pode ser usado como um CSS convencional de margin, por exemplo “10px 15px 10px 15px”. Esse valor serve para aumentar ou diminuir um espaço nos lados do elemento root antes de começar a calcular a intersecção. Por padrão é zero.
threshold: Um valor que pode variar entre 0 e 1, que indica a porcentagem e visibilidade que o componente deve aparecer para disparar o callback. Por exemplo, se o valor é 0.5, o elemento deve estar 50% visível para o callback ser disparado. Também é possível passar um array de valores para que em cada valor o callback seja executado.
Como usar isso em um custom hook ?
A ideia do custom hook que iremos criar é retornar uma referência para ser usada no elemento alvo e um booleano em que informa se o elemento alvo está visível recebendo como parâmetro as opções do nosso Intersection Observer API.
Para a referência utilizamos o hook useRef, e com o hook useState teremos o estado do elemento visível ou não, que alterado pelo nosso callback do Intersection Observer API. O próximo passo é criar o nosso callback, utilizamos o useCallback para que ele seja sempre a mesma função mesmo o componente que utilizar o custom hook tenha um re-render.
Bom, já temos nossas options e o callback, agora de fato vamos utilizar o Intersection Observer API e deixar no hook completo.
O useRef também serve para armazenar dados para serem inalterados ao houver um re-render. Ou seja, caso haja um re-render o valor da ref ainda será o da primeira renderização. Assim, na linha 45 criamos uma referência para o observer. Entre a linha 67, criamos uma instância de IntersectionObserver com nosso o callback e as options. Na linha 71, vemos se a referência do elemento está sendo utilizada para ser observada. Caso houver um re-render, a linha 65 serve para desativar nosso observer, que será o mesmo do primeiro render.
Escreva um comentário: