Manipulando o DOM com Refs
O React atualiza automaticamente oDOMpara corresponder à sua saída de renderização, portanto, seus componentes geralmente não precisam manipulá-lo. No entanto, às vezes você pode precisar acessar os elementos DOM gerenciados pelo React—por exemplo, para focar um nó, rolar até ele ou medir seu tamanho e posição. Não há uma maneira integrada de fazer essas coisas no React, então você precisará de umarefpara o nó DOM.
Você aprenderá
- Como acessar um nó DOM gerenciado pelo React com o atributo
ref - Como o atributo JSX
refse relaciona com o HookuseRef - Como acessar o nó DOM de outro componente
- Em quais casos é seguro modificar o DOM gerenciado pelo React
Obtendo uma ref para o nó
Para acessar um nó DOM gerenciado pelo React, primeiro importe o HookuseRef:
Em seguida, use-o para declarar uma ref dentro do seu componente:
Por fim, passe sua ref como o atributorefpara a tag JSX da qual você deseja obter o nó DOM:
O HookuseRefretorna um objeto com uma única propriedade chamadacurrent. Inicialmente,myRef.currentseránull. Quando o React cria um nó DOM para este<div>, o React colocará uma referência a esse nó emmyRef.current. Você pode então acessar esse nó DOM a partir dos seusmanipuladores de eventose usar asAPIs do navegadorintegradas definidas nele.
Exemplo: Focando uma entrada de texto
Neste exemplo, clicar no botão focará a entrada:
Para implementar isso:
- Declare
inputRefcom o HookuseRef. - Passe-o como
<input ref={inputRef}>. Isso diz ao React paracolocar o nó DOM deste<input>eminputRef.current. - Na função
handleClick, leia o nó DOM da entrada deinputRef.currente chamefocus()nele cominputRef.current.focus(). - Passe o manipulador de eventos
handleClickpara<button>comonClick.
Embora a manipulação do DOM seja o caso de uso mais comum para refs, o HookuseRefpode ser usado para armazenar outras coisas fora do React, como IDs de timer. Semelhante ao estado, as refs permanecem entre as renderizações. Refs são como variáveis de estado que não disparam re-renderizações quando você as define. Leia sobre refs emReferenciando Valores com Refs.
Exemplo: Rolando até um elemento
Você pode ter mais de uma única ref em um componente. Neste exemplo, há um carrossel de três imagens. Cada botão centraliza uma imagem chamando o método do navegadorscrollIntoView()no nó DOM correspondente:
Acessando os nós DOM de outro componente
Armadilha
Refs são uma saída de emergência. Manipular manualmente os nós DOM deoutrocomponente pode tornar seu código frágil.
Você pode passar refs do componente pai para componentes filhoscomo qualquer outra prop.
No exemplo acima, uma ref é criada no componente pai,MyForm, e é passada para o componente filho,MyInput.MyInputentão passa a ref para<input>. Como<input>é umcomponente integrado, o React define a propriedade.currentda ref como o elemento DOM<input>.
A inputRefcriada emMyFormagora aponta para o elemento DOM<input>retornado porMyInput. Um manipulador de clique criado emMyFormpode acessarinputRefe chamarfocus()para definir o foco no<input>.
Quando o React anexa as refs
No React, cada atualização é dividida emduas fases:
- Durante arenderização,o React chama seus componentes para determinar o que deve estar na tela.
- Durante ocommit,o React aplica as alterações ao DOM.
Em geral, vocênão deveacessar refs durante a renderização. Isso vale também para refs que contêm nós DOM. Durante a primeira renderização, os nós DOM ainda não foram criados, entãoref.currentseránull. E durante a renderização de atualizações, os nós DOM ainda não foram atualizados. Portanto, é muito cedo para lê-los.
O React defineref.currentdurante o commit. Antes de atualizar o DOM, o React define os valores deref.currentafetados paranull. Após atualizar o DOM, o React imediatamente os define para os nós DOM correspondentes.
Normalmente, você acessará refs a partir de manipuladores de eventos.Se você quiser fazer algo com uma ref, mas não houver um evento específico para fazê-lo, pode precisar de um Efeito. Discutiremos Efeitos nas próximas páginas.
Melhores práticas para manipulação do DOM com refs
Refs são uma escapatória. Você só deve usá-las quando precisar "sair do React". Exemplos comuns disso incluem gerenciar foco, posição de rolagem ou chamar APIs do navegador que o React não expõe.
Se você se limitar a ações não destrutivas como focar e rolar, não deve encontrar problemas. No entanto, se tentarmodificaro DOM manualmente, corre o risco de entrar em conflito com as alterações que o React está fazendo.
Para ilustrar esse problema, este exemplo inclui uma mensagem de boas-vindas e dois botões. O primeiro botão alterna sua presença usandorenderização condicional e estado, como você normalmente faria no React. O segundo botão usa aAPI DOM remove()para removê-la à força do DOM, fora do controle do React.
Tente pressionar "Alternar com setState" algumas vezes. A mensagem deve desaparecer e aparecer novamente. Em seguida, pressione "Remover do DOM". Isso a removerá à força. Por fim, pressione "Alternar com setState":
Depois de remover manualmente o elemento DOM, tentar usarsetStatepara mostrá-lo novamente levará a uma falha. Isso acontece porque você alterou o DOM, e o React não sabe como continuar gerenciando-o corretamente.
Evite alterar nós DOM gerenciados pelo React.Modificar, adicionar filhos ou remover filhos de elementos gerenciados pelo React pode levar a resultados visuais inconsistentes ou falhas como a acima.
No entanto, isso não significa que você não possa fazer isso de forma alguma. Requer cautela.Você pode modificar com segurança partes do DOM que o React não temrazãopara atualizar.Por exemplo, se algum<div>estiver sempre vazio no JSX, o React não terá motivo para tocar em sua lista de filhos. Portanto, é seguro adicionar ou remover elementos manualmente ali.
Recapitulação
- Refs são um conceito genérico, mas na maioria das vezes você as usará para armazenar elementos DOM.
- Você instrui o React a colocar um nó DOM em
myRef.currentpassando<div ref={myRef}>. - Normalmente, você usará refs para ações não destrutivas como focar, rolar ou medir elementos DOM.
- Um componente não expõe seus nós DOM por padrão. Você pode optar por expor um nó DOM usando a prop
ref. - Evite alterar nós DOM gerenciados pelo React.
- Se você modificar nós DOM gerenciados pelo React, modifique partes que o React não tem motivo para atualizar.
Try out some challenges
Challenge 1 of 4:Play and pause the video #
In this example, the button toggles a state variable to switch between a playing and a paused state. However, in order to actually play or pause the video, toggling state is not enough. You also need to call play() and pause() on the DOM element for the <video>. Add a ref to it, and make the button work.
For an extra challenge, keep the “Play” button in sync with whether the video is playing even if the user right-clicks the video and plays it using the built-in browser media controls. You might want to listen to onPlay and onPause on the video to do that.
