⚛Os 10 React Hooks Mais Úteis: 04 - useRef⚛
Tags: react, javascript, webdev, beginners
Published: 2022-12-26 21:48:17

_Este é o quarto artigo de uma série de 10, que explica de forma simplificada e com exemplos, os react hooks mais utilizados em programação._

---

O hook `useRef` é muito útil para criar uma **referência a um elemento DOM** ou **a um valor** dentro de um [componente funcional](https://dev.to/mpetry/componentes-funcionais-e-de-classe-em-react-150c). Ele é frequentemente usado para acessar elementos DOM ou para armazenar valores que **não precisam ser renderizados novamente** quando o componente é atualizado.
<br>
# Aplicabilidades do useRef
## Armazenar uma referência a um elemento DOM:
Aqui está um exemplo de código de como o `useRef` pode ser usado para armazenar uma referência a um elemento DOM:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/932kjq2lxx8tq0nhf0dr.png)

Neste exemplo, o `useRef` é usado para **criar uma referência** ao elemento `input`. A referência é armazenada na variável `inputElement`. Em seguida, a referência é passada para o atributo `ref` do elemento `input` usando o sintaxe `ref={inputElement}`.

Quando o botão é clicado, a função `handleButtonClick` é chamada. Ela usa a propriedade `current` da referência para acessar o elemento `input` e chama o método `focus` nele. Isso faz com que o cursor de entrada de texto seja colocado no elemento `input`.
<br>
### 1. Emprego do useRef em um elemento de lista
O caso abaixo mostra como usar o hook `useRef` para **armazenar uma referência a um elemento de lista** e **adicionar itens dinamicamente**:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygjokod1vkxxhshdpgem.png)

1 - O hook `useRef` é importado do módulo `react`, assim como o hook `useState`. 
2 - A função `MyListComponent` é criada, que renderiza o elemento de lista e um botão. 
3 - Dentro da função, é criada uma nova referência usando o hook `useRef` e a armazena na variável `listRef`. O argumento inicial `null` é passado para a função `useRef`. 
4 - O hook `useState` é usado para armazenar os itens da lista na variável `items`. 
5 - A referência é passada para o atributo `ref` do elemento de lista usando a sintaxe `ref={listRef}`. Isso faz com que a instância do elemento seja armazenada na propriedade `current` da referência. 
6 - A função `handleButtonClick` é criada para adicionar um novo item à lista e atualizar o scroll da lista para a última posição quando o botão é clicado. Ela usa o hook `useState` para adicionar um novo item à lista e atualiza a propriedade `scrollTop` da propriedade `current` da referência `listRef` para a altura total da lista usando a propriedade `scrollHeight`. 
7 - O elemento de lista e o botão são renderizados no retorno da função. Quando o botão é clicado, a função `handleButtonClick` é chamada e um novo item é adicionado à lista e o scroll da lista é atualizado para a última posição.
<br>
### 2. Hook useRef em Dropdown de menu suspenso
Imagine que você tenha um componente `Dropdown` que renderiza um menu suspenso com uma lista de opções. Você pode usar o `useRef` para armazenar uma referência ao elemento `ul` que representa o menu suspenso e, em seguida, usar essa referência para controlar a exibição do menu suspenso através da alteração da propriedade `display` do estilo do elemento:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9k89y32b7pqw8mlgb3m.png)

1 - O componente `Dropdown` recebe um array de opções como propriedade. 
2 - O componente usa o `useRef` para criar uma referência ao elemento `ul` que representa o menu suspenso. Essa referência é armazenada na variável `dropdownEl`. 
3 - O componente define uma função de manipulador de evento chamada `handleToggleDropdown` que é chamada quando o botão "Menu suspenso" é clicado. Essa função verifica o valor da propriedade `display` do elemento `ul` e altera esse valor para "block" ou "none", dependendo do seu estado atual. 
4 - O componente renderiza um botão com o texto "Menu suspenso" e um elemento `ul` com as opções passadas como propriedade. O elemento `ul` é passado a referência criada pelo `useRef` através do atributo `ref` e é inicialmente oculto com a propriedade `display` definida como "none". Quando o botão é clicado, a função `handleToggleDropdown` é chamada e altera a propriedade `display` do elemento `ul`, exibindo ou ocultando o menu suspenso.
<br>
### 3. Armazenar uma referência a um valor
O hook `useRef` pode ser usado para armazenar uma referência a um valor em um [componente funcional](https://dev.to/mpetry/componentes-funcionais-e-de-classe-em-react-150c) do React.

Ele é útil para armazenar valores que **não mudam frequentemente**, como referências a elementos do DOM, mas também pode ser usado para armazenar qualquer tipo de valor.

Por exemplo, imagine que você tenha um formulário em uma aplicação React e deseja obter o valor do `input` quando o usuário submete o formulário:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tn2nbyj5h4ymkjo3u9m.png)

1 - O componente de formulário é criado usando a função `Form`. 
2 - Dentro da função `Form`, é criada uma referência ao elemento de input usando a função `useRef`. A referência é inicializada com o valor `null`. 
3 - É definida uma função de manipulador de envio, que é chamada quando o formulário é submetido. A função chama `event.preventDefault()` para evitar que a página seja recarregada pelo navegador. 
4 - A função de manipulador de envio obtém o valor do elemento de input usando `inputEl.current.value`. 
5 - A função de manipulador de envio chama a função `submitForm` com o valor do input como argumento. 
6 - O componente é renderizado como um elemento `form` do HTML, com um manipulador de envio atribuído ao atributo `onSubmit`. Ele também renderiza um elemento `label` e um elemento `input` como filhos do elemento de formulário, além de um botão de envio. 
7 - Quando o usuário preenche o campo de entrada e clica no botão de envio, o componente obtém o valor do campo de entrada e chama a função `submitForm` com esse valor como argumento.
<br>
### 4. Armazenar referência a um objeto de websocket
O `useRef` é útil para **armazenar valores** que não precisam ser renderizados novamente quando o componente é atualizado. Por exemplo, você pode usar o `useRef` para armazenar uma referência a um objeto de [websocket](https://developer.mozilla.org/pt-BR/docs/Web/API/WebSocket#:~:text=O%20objeto%20WebSocket%20prov%C3%AA%20uma,de%20dados%20atrav%C3%A9s%20dessa%20conex%C3%A3o.), como este:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/meoquaptiqfhgacosuir.png)

1 - Neste exemplo, o hook `useRef` é usado para criar uma referência para o objeto `WebSocket`. A referência é armazenada na variável `socketRef`.
2 - Em seguida, o hook `useEffect` é usado duas vezes para configurar e limpar o objeto `WebSocket`. A primeira vez, o `useEffect` é usado para criar um novo objeto `WebSocket` quando o componente é montado. A segunda vez, o `useEffect` é usado para fechar o objeto `WebSocket` quando o componente é desmontado.
3 - Por fim, uma função `sendMessage` é criada que usa a referência para enviar mensagens pelo `WebSocket`. O componente renderiza um botão que, quando clicado, chama a função `sendMessage` para enviar uma mensagem pelo `WebSocket`.

O hook `useRef` é útil neste exemplo porque permite armazenar a referência ao objeto `WebSocket` de forma que ela não seja atualizada quando o componente é atualizado. Isso é útil porque o objeto `WebSocket` não precisa ser recriado toda vez que o componente é renderizado novamente. Em vez disso, ele pode ser acessado diretamente através da referência armazenada no `useRef`.

---

## Armazenar uma referência a uma instância de um componente de terceiros:
O hook `useRef` também pode ser usado para **armazenar uma referência a uma instância de um componente de terceiros** em um componente funcional do React.

Alguns exemplos de componentes de terceiros cujos métodos podem ser acessados usando o `useRef` incluem **bibliotecas de mapas**, **bibliotecas de gráficos**, **bibliotecas de edição de texto**, entre outros.
<br>
### 1. Hook useRef para acessar a instância de um componente de mapa
O exemplo abaixo mostra como usar o hook `useRef` para armazenar uma referência a uma instância de um componente de mapa de terceiros, neste caso o componente `GoogleMap`:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qz8qvptmjk50751ztfz.png)

1 - O hook `useRef` é importado do módulo `react` e o componente `GoogleMap` é importado de uma biblioteca de mapas. 
2 - A função `MyMapComponent` é criada, que renderiza o componente `GoogleMap` e um botão. 
3 - Dentro da função, é criada uma nova referência usando o hook `useRef` e a armazena na variável `mapRef`. O argumento inicial `null` é passado para a função `useRef`. 
4 - A referência é passada para o atributo `ref` do componente `GoogleMap` usando a sintaxe `ref={mapRef}`. Isso faz com que a instância do componente seja armazenada na propriedade `current` da referência. 
5 - A função `handleButtonClick` é criada para recentralizar o mapa quando o botão é clicado. Ela usa a propriedade `current` da referência `mapRef` para acessar o método `recenter` do componente de mapa e passa as coordenadas de latitude e longitude como argumento. 
6 - O componente `GoogleMap` e o botão são renderizados no retorno da função. Quando o botão é clicado, a função `handleButtonClick` é chamada e o mapa é recentralizado nas coordenadas especificadas.
<br>
### 2. useRef para acessar bilbiotecas de gráficos
O modelo abaixo mostra como usar o hook `useRef` para armazenar uma referência a uma instância de um **componente de gráfico** de terceiros, neste caso o componente `Chart`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uxgay3dhfwe6fyhk1lo.png)

1 - O hook `useRef` é importado do módulo `react` e o componente `Chart` é importado de uma biblioteca de gráficos.
2 - A função `MyChartComponent` é criada, que renderiza o componente `Chart` e um botão. 
3 - Dentro da função, é criada uma nova referência usando o hook `useRef` e a armazena na variável `chartRef`. O argumento inicial `null` é passado para a função `useRef`. 
4 - A referência é passada para o atributo `ref` do componente `Chart` usando a sintaxe `ref={chartRef}`. Isso faz com que a instância do componente seja armazenada na propriedade `current` da referência. 
5 - A função `handleButtonClick` é criada para atualizar os dados do gráfico quando o botão é clicado. Ela usa a propriedade `current` da referência `chartRef` para acessar o método `update` do componente de gráfico e passa um novo conjunto de dados como argumento. 
6 - O componente `Chart` e o botão são renderizados no retorno da função. Quando o botão é clicado, a função `handleButtonClick` é chamada e os dados do gráfico são atualizados com os novos valores.
<br> 
### 3. Hook useRef para armazenar uma referência a um componente de edição de texto

Ainda, podemos utilizar o `useRef` para **armazenar uma referência a uma instância de um componente de edição de texto de terceiros**, neste caso o componente `Quill`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tpy19h89ailq3mbj8kv.png)

1 - O hook `useRef` é importado do módulo `react` e o componente `Quill` é importado de uma biblioteca de edição de texto. 
2 - A função `MyEditorComponent` é criada, que renderiza o componente `Quill` e um botão. 
3 - Dentro da função, é criada uma nova referência usando o hook `useRef` e a armazena na variável `editorRef`. O argumento inicial `null` é passado para a função `useRef`. 
4 - A referência é passada para o atributo `ref` do componente `Quill` usando a sintaxe `ref={editorRef}`. Isso faz com que a instância do componente seja armazenada na propriedade `current` da referência.
5 - A função `handleButtonClick` é criada para limpar o conteúdo do editor quando o botão é clicado. Ela usa a propriedade `current` da referência `editorRef` para acessar o método `setText` do componente de edição de texto e passa uma string vazia como argumento. 
6 - O componente `Quill` e o botão são renderizados no retorno da função.

---
# Conclusão

O `useRef` é um hook do React que permite armazenar uma referência a um valor. Ele é útil para armazenar valores que não mudam frequentemente, como referências a elementos do DOM, mas também pode ser usado para armazenar qualquer tipo de valor. O `useRef` é um jeito conveniente de acessar elementos do DOM em uma aplicação React e pode ser usado em conjunto com outros hooks, como o `useEffect`, para realizar tarefas em resposta a mudanças no estado ou propriedades de um componente. 

Um dos usos mais comuns do `useRef` é para acessar valores de elementos do DOM em uma aplicação React. Por exemplo, o `useRef` pode ser usado para obter o valor de um campo de entrada em um formulário ou para obter a altura ou largura de um elemento na página. Além disso, o `useRef` pode ser usado para armazenar instâncias de objetos de terceiros, como bibliotecas de mapas ou gráficos, e acessar os métodos e propriedades desses objetos.

A importância do `useRef` reside em sua capacidade de fornecer acesso a valores que não são gerenciados pelo estado do React ou pelas props de um componente. Isso é especialmente útil em situações em que você deseja acessar ou alterar valores em resposta a eventos ou mudanças no estado do componente, mas não quer renderizar o componente novamente quando esses valores mudam.

Portanto, o `useRef` é uma ferramenta útil para acessar e armazenar valores em uma aplicação React e pode ser usado em conjunto com outros hooks para realizar tarefas em resposta a mudanças no estado ou propriedades de um componente. Ao usar o `useRef`, é importante lembrar de atribuir a referência ao atributo `ref` do elemento ao qual você deseja ter acesso e lembrar de usar `.current` para acessar o valor armazenado na referência.

---

[marcelopetry.com](https://marcelopetry.com)