Referenciando Valores com Refs
Quando você quer que um componente "lembre" alguma informação, mas não quer que essa informaçãodispare novas renderizações, você pode usar umaref.
Você vai aprender
- Como adicionar uma ref ao seu componente
- Como atualizar o valor de uma ref
- Como as refs são diferentes do state
- Como usar refs com segurança
Adicionando uma ref ao seu componente
Você pode adicionar uma ref ao seu componente importando o HookuseRefdo React:
Dentro do seu componente, chame o HookuseRefe passe o valor inicial que você quer referenciar como único argumento. Por exemplo, aqui está uma ref para o valor0:
useRefretorna um objeto como este:

Ilustrado porRachel Lee Nabors
Você pode acessar o valor atual dessa ref através da propriedaderef.current. Esse valor é intencionalmente mutável, o que significa que você pode tanto ler quanto escrever nele. É como um bolso secreto do seu componente que o React não rastreia. (É isso que o torna uma "saída de emergência" do fluxo unidirecional de dados do React—mais sobre isso abaixo!)
Aqui, um botão irá incrementarref.currenta cada clique:
A ref aponta para um número, mas, assim como ostate, você poderia apontar para qualquer coisa: uma string, um objeto ou até uma função. Diferente do state, uma ref é um objeto JavaScript simples com a propriedadecurrentque você pode ler e modificar.
Observe queo componente não é renderizado novamente a cada incremento.Assim como o state, as refs são mantidas pelo React entre re-renderizações. No entanto, definir o state re-renderiza um componente. Alterar uma ref não!
Exemplo: construindo um cronômetro
Você pode combinar refs e state em um único componente. Por exemplo, vamos fazer um cronômetro que o usuário pode iniciar ou parar pressionando um botão. Para exibir quanto tempo passou desde que o usuário pressionou "Iniciar", você precisará rastrear quando o botão Iniciar foi pressionado e qual é a hora atual.Esta informação é usada para renderização, então você a manterá no state:
Quando o usuário pressionar "Iniciar", você usarásetIntervalpara atualizar o tempo a cada 10 milissegundos:
Quando o botão "Parar" for pressionado, você precisa cancelar o intervalo existente para que ele pare de atualizar a variável de statenow. Você pode fazer isso chamandoclearInterval, mas precisa fornecer o ID do intervalo que foi retornado anteriormente pela chamadasetIntervalquando o usuário pressionou Iniciar. Você precisa guardar o ID do intervalo em algum lugar.Como o ID do intervalo não é usado para renderização, você pode guardá-lo em uma ref:
Quando uma informação é usada para renderização, mantenha-a no estado. Quando uma informação é necessária apenas por manipuladores de evento e alterá-la não requer uma re-renderização, usar uma ref pode ser mais eficiente.
Diferenças entre refs e estado
Talvez você pense que as refs parecem menos "rígidas" que o estado — você pode mutá-las em vez de sempre precisar usar uma função de definição de estado, por exemplo. Mas na maioria dos casos, você vai querer usar estado. Refs são uma "válvula de escape" que você não precisará com frequência. Aqui está uma comparação entre estado e refs:
| refs | estado |
|---|---|
useRef(initialValue)retorna{ current: initialValue } | useState(initialValue)retorna o valor atual de uma variável de estado e uma função definidora de estado ([value, setValue]) |
| Não dispara re-renderização quando você a altera. | Dispara re-renderização quando você a altera. |
Mutável — você pode modificar e atualizar o valor decurrentfora do processo de renderização. | "Imutável" — você deve usar a função definidora de estado para modificar variáveis de estado e enfileirar uma re-renderização. |
Você não deve ler (ou escrever) o valor decurrentdurante a renderização. | Você pode ler o estado a qualquer momento. No entanto, cada renderização tem seu próprioinstantâneodo estado que não muda. |
Aqui está um botão de contador implementado com estado:
Como o valor decounté exibido, faz sentido usar um valor de estado para ele. Quando o valor do contador é definido comsetCount(), o React re-renderiza o componente e a tela é atualizada para refletir a nova contagem.
Se você tentasse implementar isso com uma ref, o React nunca re-renderizaria o componente, então você nunca veria a contagem mudar! Veja como clicar neste botãonão atualiza seu texto:
É por isso que lerref.currentdurante a renderização leva a código não confiável. Se você precisar disso, use estado.
Quando usar refs
Tipicamente, você usará uma ref quando seu componente precisar "sair" do React e se comunicar com APIs externas—frequentemente uma API do navegador que não afetará a aparência do componente. Aqui estão algumas dessas situações raras:
- ArmazenarIDs de timeout
- Armazenar e manipularelementos DOM, que abordamos napróxima página
- Armazenar outros objetos que não são necessários para calcular o JSX.
Se seu componente precisa armazenar algum valor, mas isso não afeta a lógica de renderização, escolha refs.
Melhores práticas para refs
Seguir estes princípios tornará seus componentes mais previsíveis:
- Trate refs como uma saída de emergência.Refs são úteis quando você trabalha com sistemas externos ou APIs do navegador. Se grande parte da lógica e do fluxo de dados do seu aplicativo depender de refs, você pode querer reconsiderar sua abordagem.
- Não leia nem escreva em
ref.currentdurante a renderização.Se alguma informação for necessária durante a renderização, useestado. Como o React não sabe quandoref.currentmuda, mesmo lê-lo durante a renderização torna o comportamento do seu componente difícil de prever. (A única exceção a isso é código comoif (!ref.current) ref.current = new Thing()que define a ref apenas uma vez durante a primeira renderização.)
As limitações do estado do React não se aplicam a refs. Por exemplo, o estado age como uminstantâneo para cada renderização e não atualiza de forma síncrona.Mas quando você altera o valor atual de uma ref, ele muda imediatamente:
Isso ocorre porquea própria ref é um objeto JavaScript comum,e portanto se comporta como um.
Você também não precisa se preocupar emevitar mutaçãoao trabalhar com uma ref. Contanto que o objeto que você está alterando não seja usado para renderização, o React não se importa com o que você faz com a ref ou seu conteúdo.
Refs e o DOM
Você pode apontar uma ref para qualquer valor. No entanto, o caso de uso mais comum para uma ref é acessar um elemento DOM. Por exemplo, isso é útil se você quiser focar um input programaticamente. Quando você passa uma ref para um atributorefem JSX, como<div ref={myRef}>, o React colocará o elemento DOM correspondente emmyRef.current. Uma vez que o elemento é removido do DOM, o React atualizarámyRef.currentparanull. Você pode ler mais sobre isso emManipulando o DOM com Refs.
Recapitulação
- Refs são uma escotilha de escape para armazenar valores que não são usados para renderização. Você não precisará deles com frequência.
- Uma ref é um objeto JavaScript simples com uma única propriedade chamada
current, que você pode ler ou definir. - Você pode pedir ao React para lhe dar uma ref chamando o Hook
useRef. - Assim como o estado, refs permitem que você retenha informações entre as re-renderizações de um componente.
- Diferente do estado, definir o valor
currentda ref não aciona uma re-renderização. - Não leia nem escreva
ref.currentdurante a renderização. Isso torna seu componente difícil de prever.
Experimente alguns desafios
Challenge 1 of 4:Corrija uma entrada de bate-papo quebrada #
Digite uma mensagem e clique em “Enviar”. Você notará que há um atraso de três segundos antes de ver o alerta “Enviado!”. Durante este atraso, você pode ver um botão “Desfazer”. Clique nele. Este botão “Desfazer” deve impedir que a mensagem “Enviado!” apareça. Ele faz isso chamando clearTimeout para o ID do timeout salvo durante handleSend. No entanto, mesmo depois que “Desfazer” é clicado, a mensagem “Enviado!” ainda aparece. Descubra por que não funciona e corrija.
