Referenciando componentes no React

Javascript

Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar componentes através do atributo ref.

Porque referenciar componentes?

Através do atributo ref conseguimos acessar elementos do DOM ou do React criados durante o método render. Com a referência podemos realizar modificações ou disparar funções de componentes pais para os seus filhos, e até mesmo realizar interações no DOM referente ao componente renderizado.

Obs: Evite utilizar o ref para exemplos ou necessidades que podem ser feitas de forma declarativa através dos componentes.

Como referenciar componentes?

Atualmente, se você já trabalhou com React antes, deve se lembrar da String Ref API:

<MeuBotao ref="meuBotao"/>

Dessa maneira, estamos atribuindo uma nova propriedade para nossa classe chamada meuBotao, podemos acessá-la dentro de outras funções através de this.meuBotao.

Porém essa forma esta como legacy e provavelmente em um futuro próximo será depreciada (deprecated), pois possuem vários efeitos colaterais, então como devemos fazer?

Pensando em como referenciar componentes

Nova API de referenciamentos

Á partir da versão 16.3.0 do React, foi disponibilizado uma nova API chamada de createRef, é exatamente através dela que devemos referenciar nossos componentes ou elementos do DOM, o uso deve ser feito da seguinte maneira:

  1. Criar uma propriedade de classe para armazenar o ref.
  2. Passar essa propriedade para quem deve ser referenciado.

Criando a propriedade de classe

Através do constructor (construtor), podemos criar essa propriedade da classe:

constructor(props) {
    super(props)
    this.meuBotao = React.createRef()
}

Se você preferir, podemos evitar a necessidade de uso do React fazendo a importação da função createRef, da seguinte maneira:

import React, { createRef } from "react"

// ... demais códigos

constructor(props) {
    super(props)
    this.meuBotao = createRef()
}

Fica a seu critério e gosto particular para decidir de qual forma utilizar.

Agora já temos onde salvar o nosso referenciado, precisamos apenas realizar a referência.

Referenciando o componente

Para vincular nosso componente para a propriedade this.meuBotao, ainda continuamos utilizando o atributo ref:

<MeuBotao ref={ this.meuBotao }/>

Apenas passamos a propriedade de classe que foi criada através da função createRef.

Acessando uma referência

Para acessar a referência dentro de alguma função ficou um pouco diferente, antes podiamos fazer algo do tipo:

this.meuBotao.focus()

Porém, com essa nova API, a nossa referência fica dentro de current, portanto, para acessar um botão por exemplo, devemos fazer:

this.meuBotao.current.focus()

Vale observar que:

  • Se o referenciado é um componente de classe do React, o current recebe esse componente montado.
  • Se o referenciado é um elemento HTML, o current irá receber o elemento do DOM ao qual aquele HTML está associado.

Referenciando através de Callbacks

Também podemos realizar referencias através de callback's:

<MeuBotao ref={ meuBotao => this.meuBotao = meuBotao }/>

Porém, aqui entra um detalhe, se fizermos dessa maneira o React irá chamar o ref duas vezes, a primeira com null e a segunda com a referência de fato. Isso acontece porque novas instâncias são criadas para cada render, então o React precisa limpar a referência antiga para setar a nova.

Vale lembrar que apesar de existir uma nova API para realizar a referência, a forma através de callback's ainda será suportada.

Redirecionando uma referência

Em alguns casos, você pode querer acessar a referência de uma referência (não recomendado, isso irá contra o encapsulamento de componentes), porém, tudo é possível e cada caso é um caso. Para tal necessidade foi disponilizado a função forwardRef, dessa maneira, conseguimos referenciar um filho como se fosse o próprio pai, por exemplo:

<MeuBotao ref={ this.meuBotao }/>

Essa referência será feita para a instância do componente MeuBotao, porém, eu quero acessar o button que está sendo renderizado pelo MeuBotao, como podemos fazer isso? Basicamente devemos repassar o ref recebido pelo MeuBotao para o button:

const MeuBotao = React.forwardRef(({ children }, ref) => (
    <button ref={ ref }>
        { children }
    </button>
))

Obs: Assim como foi feito com o createRef, a função forwardRef também pode ser importada e usada de forma isolado ao React.

Repare que estamos utilizando a função forwardRef, sem ela não seria possível receber o ref para repassá-lo para nosso filho, a função irá devolver um componente do React.

Saiba mais

Quando o referenciado é desmontado, a referência recebe o valor null.

Componentes Funcionais (Functional Components) não podem ser referenciados, isso porque eles não possuem a instância de uma classe. Caso seja necessário, você pode estar convertendo-o para um Componente de Classe (Class Component).

Apensar de Componentes Funcionais não poderem ser referenciados, dentro deles você pode utilizar o atributo ref e fazer referências para outros componentes ou elementos HTML sem problemas.

Referências são atualizadas antes dos ciclos de vida: componentDidMount e componentDidUpdate.

Conclusão

Nesse post eu falei um pouco sobre referências de componentes ou elementos HTML, expliquei o novo jeito de fazer com a createRef e também expliquei como passar uma referência de pai para filhos com o forwardRef.

E aí, você já conhecia as novas API's? Não deixe de comentar, se você gostou do post se inscreva na newsletter para estar recebendo novidades por email.

Até a próxima.

Matheus Castiglioni

Matheus Castiglioni

Apaixonado pelo mundo dos códigos e um eterno estudante, gosto de aprender e saber um pouco de tudo, aquela curiosidade de saber como tudo funciona, tento compartilhar o máximo de conhecimentos adquiridos e ajudar todos aqueles que sou capaz.

Post's Relacionados

Visualize outros post's relacionados ao mesmo assunto:

Atualizando estado dos componentes no React

Javascript
Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar component...
Continuar lendo

Mantendo estados de componentes no React com state

Javascript
Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar component...
Continuar lendo

String em JavaScript com aspas simples ou duplas?

Javascript
Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar component...
Continuar lendo

Listando tarefas com React

Javascript
Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar component...
Continuar lendo

Primeiros passos com TypeScript

Javascript
Continuando a série de post's sobre React, no post anterior eu expliquei com mais detalhes o funcionamento da função setState e mostrei possíveis maneiras que podemos estar a utilizando. Para assunto desse post irei explicar como referenciar component...
Continuar lendo