Formas de Escrever Componentes React

NCB{code}
4 min readDec 1, 2018

--

Quando comecei a trabalhar com React, uma das coisas que sempre me deixava confuso era que a maneira como as pessoas escreviam os componentes não era consistente: alguns usavam funções, outros estendiam a classe Component e outros estendiam a PureComponent. Sempre acabava me perguntando, qual a melhor forma de se usar? O que motiva escolher uma forma ou outra? Hoje vou abordar um pouco desses assuntos e compartilhar o que aprendi.

Usarei como base a última versão disponível da biblioteca na data desta publicação (16.6.3) e o código dos exemplos está em ES6. Irei considerar que o leitor possui conhecimento básico em React (props, state, lifecycle…).

Function Components

Desde a versão 0.14 do React é possível escrever componentes em forma de funções e hoje é a forma mais simples e clean de escrevê-los. Basicamente se resume a uma simples função javascript que recebe os props e deve retornar um elemento:

Ou sendo ainda mais sucinto:

A principal vantagem de se escrever desta forma é a sintaxe reduzida, menor complexidade e a consequente maior clareza no código. Apesar dessa simplicidade, atualmente não existem otimizações de performance out-of-the-box em comparação com as classes. As principais desvantagens incluem:

  • sem estadopor isso muitas vezes são chamados de stateless functional components;
  • sem métodos do ciclo de vida;
  • não poder criar métodos para o seu componente que serão expostos a terceiros (um método focus, por exemplo)

Pode parecer que as desvantagens são muitas, mas se encaixa perfeitamente nas necessidades da maioria dos componentes “burros” ou que são puramente de apresentação (UI).

Desde a versão 16.6.0 do React existe uma forma de otimizar a performance dos function components (de forma semelhante ao que já era possível em class components — falarei sobre eles mais a frente):

Se o seu componente sempre renderiza o mesmo resultado dado os mesmos props, você pode encapsula-lo usando o React.memo, desta forma a renderização será pulada em alguns casos, melhorando a performance. Por padrão é feita uma comparação rasa dos props para verificar se houve mudança, ou seja, se existirem objetos complexos no props, apenas as referências serão comparadas. Se você usa Redux e objetos imutáveis, isso deve ser o suficiente, caso você precise de mais controle, você pode passar como segundo argumento para o memo uma função de comparação. Para mais informações em como fazer isso, acesse aqui a documentação oficial.

Class Components

Diria que é a forma tradicional de escrever componentes, já que está disponível desde as primeiras versões. Para escrever um componente você deve estender a classe Component e implementar a função render:

É a forma mais flexível de escrita, já que com ela você pode usar features como estado interno (state), métodos do ciclo de vida (lifecycle) e tem controle sobre a API externa do seu componente:

Para otimizar a performance existe o método shouldComponentUpdate. O comportamento padrão é apenas retornar true, ou seja, sempre que algum prop ou state for recebido o componente será renderizado novamente. A segunda opção para otimização (e recomendada — só use o shouldComponentUpdate se realmente souber o que esta fazendo) é herdar da classe PureComponent ao invés da Component:

A diferença entre as duas é que na PureComponent o método shouldComponentUpdate realiza por padrão uma comparação rasa do props e do state, desta forma pulando algumas renderizações desnecessárias. De forma análoga ao React.memo, você só deve usar o PureComponent se o seu componente sempre renderiza o mesmo resultado dados os mesmos props e state.

Conclusão

Pessoalmente, tenho uma tendência a usar function components (código mais claro e conciso) para componentes de apresentação sempre que for possível — que não tenham estado interno e não usam o ciclo de vida; e class components para os componentes mais complexos e que estão mais ligados ao comportamento da aplicação (“containers” — ainda vou escrever mais sobre esse assunto).

Existem equipes que preferem escrever tudo em class components como forma de padronizar o código, o que pode levar a um aumento de produtividade, não existe certo ou errado nesse caso. O importante é entender os porquês e usar as ferramentas disponíveis adequadamente.

--

--