Criando custom Hook para capturar o width da tela em ReactJs
Published: 2022-12-13 14:32:12

Uma forma prática de utilizar o valor da largura de uma tela (screenWidth) em ReactJs usando Javascript, é utilizando uma metodologia disponibilizada pelo próprio React para gerenciarmos nossas aplicações, os Custom Hooks.

Com esse método de captura do screenWidth conseguimos utilizar o valor atual da largura de tela para criarmos diversos tipos de lógica em nossa aplicação, como uma renderização condicional de um header por exemplo. 

### Conceito de Custom Hook

Custom Hooks foram implementados na versão 16.8 do React, e ele dá a possibilidade de utilizar recursos do React como gerenciamento de estado sem precisarmos necessariamente de uma classe para isso.

Você pode ler um pouco sobre Custom Hooks na própria documentação do React bem [aqui.]('https://reactjs.org/docs/hooks-custom.html')

Criar hooks para diferentes funcionalidades é bem útil quando precisamos de o valor de forma recorrente no nosso código. Não existe nenhuma regra geral para se criar hooks ou funções, mas eu, particularmente, crio novos hooks sempre que preciso lidar com valores que dependem de um estado. 

Vamos então para a parte prática da criação do hook.

```
export const useScreenWidth = () => {
  const [screenWidth, setScreenWidth] = useState<number>(window.innerWidth)

  const handleWindowSizeChange = () => {
    setScreenWidth(window.innerWidth)
  }

  useEffect(() => {
    window.addEventListener('resize', handleWindowSizeChange)
    return () => {
      window.removeEventListener('resize', handleWindowSizeChange)
    }
  }, [])

  return screenWidth
}
```
O nome de um hook por padrão é sempre iniciado com a palavra "use" seguido do objetivo daquele hook. Utilizaremos isso como regra para criar nossos futuros hooks.

1 - Inicialmente criamos um hook chamado useScreenWidth. É muito importante que utilizamos sempre a regra de criação de nomes de hooks, essa nomeclatura é obrigatória para que o react entenda que o que estamos criando é um customHook.

2 - Criamos um estado chamado screenWidth, será esse o valor que utilizaremos na nossa aplicação.

3 - Em seguida criamos uma nova função chamada `handleWindowSizeChange` que capturará o valor da largura da tela através da propriedade `window.innerWidth` e armazenará dentro do nosso estado `screenWidth` a largura da tela através da função `setScreenWidth()`. A propriedade `window.innerWidth` é nativa do Javascript e retorna a largura interior de uma janela em pixels. Você pode ler mais sobre [aqui.]('https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth')

4 - Precisamos observar os valores da tela para que possamos retornar para nossa aplicação, desse modo, utilizaremos um useEffect, hook nativo do React que tem como objetivo causar um efeito colaterais na nossa aplicação. Dentro desse efeito utilizaremos o método `window.addEventListener` que basicamente especifica uma função que será executada sempre que o evento especificado acontecer. No nosso caso, o evento esperado é o resize da tela. Desse modo, sempre que a tela sofrer alterações em suas dimensões executaremos a função `handleWindowSizeChange` especificada no item 3.

5 - O React executa a limpeza sempre que o componente desmonta. Entretanto, efeitos rodam em todas as renderizações de um componente, e não apenas uma vez. Sendo assim, o React deve limpar os efeitos da renderização anterior antes de rodar os efeitos da próxima vez. Desse modo, é suma importância que evitemos o memory leak, ou vazamento de memória especificando quando o nosso hook deve remover o listener para que possamos evitar esse vazamento. Logo, retornamos a remoção do listener através do método `window.removeEventListener` 

7 - É importante lembrar que nosso efeito não contém dependências pois ele não depende de nenhuma variável externa para ser executada.

6 - Por ultimo retornamos o nosso estado para que possa ser utilizado pela nossa aplicação.

Após a criação do nosso hook podemos chama-lo em qualquer componente de nossa aplicação apenas com o código abaixo:

```
const screenWidth = useScreenWidth()
```

Desse modo, a constante screenWidth estará disponível para ser utilizada sempre que quisermos.

### Referências

Como sugestão de leitura deixo aqui a documentação do próprio React para quem quiser se aprofundar mais na utilização de hooks.

[React Hooks]('https://reactjs.org/docs/hooks-intro.html')