Desenvolvimento

10 ago, 2017

O guia completo do React e o seu ecossistema

Publicidade

Você ouve falar frequentemente sobre o React, mas sabe pouco sobre assunto? Ou já até estudou a respeito da biblioteca desenvolvida pelo Facebook, mas quer consolidar seus conhecimentos?

Então este artigo é para você.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Introdução

Para começar, precisamos saber o que é o React. Para isso, não há nada melhor do que utilizar a definição de quem o criou, o próprio Facebook:

Uma biblioteca JavaScript declarativa, eficiente e flexível para criar interfaces visuais.

Com isso, sabemos que:

  • O React não é um framework, mas uma biblioteca (library);
  • O React serve para criar interfaces visuais (UI).

Essas duas informações juntas criam a primeira grande confusão para quem está começando: se o React é apenas uma biblioteca e só serve para criar UI, como posso criar aplicações completas com ele?

Para resolver esta questão precisamos entender que quando a comunidade se refere ao React ela está querendo dizer ‘o React e o seu ecossistema‘. E esse ecossistema é formado por:

  • React
  • JSX
  • ES2015
  • Webpack
  • Flux/Redux
  • Axios/Fetch
  • Jest/Mocha

 

Assim, com todos esses itens que fazem parte do ecossistema do React, conseguimos afirmar que é possível sim criar aplicações completas usando ele.

JSX

Explicando de forma rápida, o JSX é uma extensão de sintaxe do JavaScript (daí o nome JavaScript Syntax eXtension) que nos permite escrever HTML dentro do JavaScript.

Nos primórdios, o JSX era um dos grandes motivos das críticas e piadas em relação ao React, porque, em teoria, estávamos voltando no tempo ao misturar HTML com JavaScript.

Os críticos mais ferrenhos afirmavam que o JSX quebrava um dos princípios básicos do desenvolvimento de software, que é o Separation of Concerns. Na minha opinião, essa visão é errada por dois motivos:

  • O React em si, a biblioteca e não o ecossistema, como já falei anteriormente, representa apenas a parte da view da sua aplicação. Portanto, por definição, ele tem apenas um concern: renderizar a UI. Então quais concerns estão sendo violados?
  • E mesmo que o JSX violasse esse princípio a área de tecnologia evolui (e muito) com o tempo. Se um dos princípios que nós sempre demos como verdade não fizer mais sentido para um determinado cenário, deveremos nos forçar a seguir esse princípio mesmo assim?

 

Independente das minhas opiniões pessoais, com o tempo a comunidade percebeu que o JSX foi uma decisão acertada e que acabou se tornando um dos grandes alicerces do sucesso do React.

Componentes

Como foi dito anteriormente, o React tem como função principal auxiliar na criação da UI. Só deixei um detalhe importante de fora: o React usa componentes e apenas componentes para que seja possível aumentar o máximo do reuso em sua aplicação.

Para exemplificar, vamos ver um pouco de código para entender como é um componente React:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

A função acima (sim, componentes React podem ser simplesmente funções em JavaScript) gera um botão que mostra um alert para o usuário ao ser clicado.

Se precisarmos de outro botão como esse, basta reaproveita-lo sem a necessidade de adicionar mais código na aplicação. Lembrando que ‘mais código’ é sinônimo de mais trabalho, mais testes unitários e mais potenciais bugs inseridos.

E se a necessidade for um botão parecido com esse, basta editarmos passando por alguns parâmetros (vamos falar mais sobre eles na próxima seção) para transformá-lo no que precisamos.

Se houver algum bug no comportamento, ou mesmo no layout do botão, sabemos exatamente onde devemos mexer no código para fazer o conserto rápido.

Em resumo, os componentes em React nos deixam mais produtivos. Com eles temos um reaproveitamento de código maior e uma menor probabilidade de novos bugs a serem introduzidos na aplicação.

Props

Em todos os tipos de paradigmas no desenvolvimento de software, passar parâmetros é extremamente comum. Com os componentes do React isso não poderia ser diferente. A diferença é que no React usamos os props (abreviação para properties).

A ideia é simples.

O componente abaixo mostra para o usuário um Hello World:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Imaginando que precisamos mudar a mensagem ‘World’ para alguma outra que for enviada dinamicamente, podemos reescrever esse componente usando as props dessa forma:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Com isso feito, podemos chamar esse componente dentro de outros, dessa maneira:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Além disso, podemos fazer uma validação das props que são passadas pelo componente para evitar bugs desnecessários e assim facilitar o desenvolvimento da aplicação usando os PropTypes:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Agora, informamos explicitamente ao React para que apenas aceite a prop quando ela for uma string. Se qualquer outra coisa for passada para esse componente, a aplicação irá falhar e receberemos uma mensagem de erro nos avisando o porquê.

Para ler mais sobre os PropTypes, entre na documentação completa na própria página do React.

O Flow e o TypeScript são outras possibilidades para lidar com os PropTypes.

State

O estado (ou state) da sua aplicação pode ser definido como o lugar onde os dados vêm e se transformam ao longo do tempo. Dito isso, os componentes React podem ser divididos em duas categorias: Presentational e Container. Outra nomenclatura usada na comunidade para esses dois é Stateless (sem estado) e Stateful (com estado).

Os componentes do tipo Presentational se importam somente com a apresentação dos dados, portanto não tem estado (stateless). Eles podem ser escritos como uma simples função:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

O ideal é escrever o máximo possível de componentes dessa categoria; eles são mais fáceis de desenvolver, manter e testar.

Já os componentes do tipo Container, além da apresentação dos dados, têm que lidar também com algum tipo de lógica ou transformação de dados, por isso necessitam de estado (stateful). Esses componentes não podem ser escritos como uma função, eles obrigatoriamente devem ser uma classe:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Os dois exemplos mostrados acima têm exatamente o mesmo resultado final. A única diferença é que o primeiro deles não usa o state do React, enquanto o segundo usa.

Podemos ainda complicar um pouco mais o segundo exemplo para demonstrar como é possível alterar o estado do seu componente React:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Em cada mudança que ocorrer no input (linha 16) um evento é disparado na função change, que por sua vez altera o estado do componente usando a função setState, nativa do React.

Toda vez que o estado for alterado o React automaticamente invoca de novo a função render, que irá renderizar a UI com os novos dados inputados pelo usuário.

One-way data binding

É bem mais fácil falar dos benefícios do one-way data binding (ou one-way data flow) demonstrando o fracasso do seu “concorrente”, o two-way data binding.

O Angular.js ganhou muitos usuários, principalmente entre 2012 e 2015, e um dos principais motivos disso foi justamente o two-way data binding.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA
https://docs.angularjs.org/guide/databinding

O two-way data binding funciona assim: se uma mudança acontece na view, ela é refletida automaticamente no model, e vice-versa.

No começo, o two-way data binding parecia uma excelente ideia. Com o tempo, após inúmeros projetos construídos usando essa tecnologia, ela se mostrou extremamente nociva principalmente por dois motivos:

 

A própria equipe do Angular resolveu limitar essa funcionalidade nas novas versões do framework.

O React porém, percebeu essa falha desde o início e estimulou apenas o uso do one-way data binding.

Não existe um mecanismo no React que permita com que o HTML altere os dados do componente ou vice-versa. Essa mudança é sempre feita de forma explícita pelo desenvolvedor. Lembrando que explícito é muito melhor em termos de desenvolvimento, manutenção e testes, do que implícito.

Um exemplo simples de one-way data binding em ação no React pode ser visto no componente abaixo:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Se estivéssemos no mundo two-way data binding do Angular.js, o model e a view estariam conectados implicitamente e ambos mudariam juntos.

Porém, com o one-way data binding do React, precisamos explicitamente invocar a função setState para que o estado seja alterado. Dessa forma temos muito mais previsibilidade e segurança da nossa aplicação, o que fica evidente conforme a aplicação cresce.

Lifecycle

Para que seja possível o desenvolvimento de componentes mais complexos, alguns métodos foram adicionados na API dos componentes React. Eles fazem parte do Component Lifecycle (ciclo de vida dos componentes).

Com esses métodos, os desenvolvedores podem saber, por exemplo, quando um componente vai ser criado, destruído, atualizado etc.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

São esses os métodos de Lifecycle dos componentes:

  • componentWillMount: executado logo antes do primeiro render. Não é muito usado, geralmente faz mais sentido simplesmente usar o próprio construtor da classe;
  • componentDidMount: executado logo após o primeiro render, provavelmente o método mais usado. Alguns exemplos de casos de uso são: chamadas AJAX, manipulação do DOM, início de setTimeouts e setIntervals etc;
  • componentWillReceiveProps: executado quando as props que o componente recebe são atualizadas. Geralmente é usado quando os componentes precisam reagir aos eventos externos;
  • componentWillUpdate: é igual ao componentWillMount, só que ele executa logo antes da atualização de um componente;
  • componentDidUpdate, é igual ao componentDidMount, só que ele executa logo depois da atualização de um componente.
  • componentWillUnmount, executado quando o ciclo de vida de um componente termina e ele vai ser removido do DOM. É muito usado para remover setTimeouts e setIntervals que foram adicionados.
  • shouldComponentUpdate, deve retornar true/false. Esse valor vai dizer que se o componente deve ser atualizado ou não, com base em certos parâmetros. Geralmente é usado para resolver questões de performance.

 

Um exemplo simples de uso dos métodos de lifecycle é o contador de segundos abaixo:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Assim que o componente é montado (componentDidMount), iniciamos o setInterval que a cada 1000ms invoca a função tick. E quando o componente for destruído (componentWillUnmount) removemos o setInterval para que a função tick não continue sendo chamada desnecessariamente.

Virtual DOM

A manipulação do DOM está no centro do desenvolvimento front-end moderno. Fazemos isso basicamente todos os dias, o que acarreta dois problemas:

  • Essa manipulação direta do DOM é mais lenta do que a maioria das operações feitas pelo JavaScript;
  • A maioria dos frameworks JavaScript alteram muito mais o DOM do que deveriam.

 

Sabendo disso, o Facebook criou o Virtual DOM, que funciona da seguinte forma: no React, uma cópia de todos os nodes do DOM são replicados em código JavaScript. Em vez de fazer alterações diretamente no DOM (que são lentas) elas são feitas no Virtual DOM (rápidas) e somente quando realmente necessário, essas alterações são repassadas para o DOM original.

Esse é um dos principais motivos para os excelentes benchmarks de performance que o React tem.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Agora que já entendemos as partes fundamentais do React, precisamos entender também o seu ecossistema.

create-react-app

Nos primeiros anos do React, uma das principais críticas era de que iniciar uma aplicação era muito mais complicada do que deveria ser, o que acabava excluindo diversos iniciantes.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Antes de sequer começar a primeira linha de código em React, os desenvolvedores precisavam aprender no mínimo o Webpack e ES2015.

Hoje isso não é mais um problema. A equipe do Facebook vem trabalhando diariamente no projeto create-react-app, logo, agora com apenas quatro simples comandos, sem ter que criar ou editar qualquer configuração, temos um arcabouço completo para começar a desenvolver aplicações em React.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

CSS-in-JS

Todas as boas práticas ao se escrever CSS apontavam para um mesmo caminho por anos: escrever CSS o mais desacoplado possível do JavaScript e do HTML, usando nomes bem descritivos para as classes.

O problema dessa abordagem é que ela não resolve o maior defeito do CSS: tudo o que você cria é global.

Cada vez que você cria uma nova classe CSS ela é, por definição, global, o que gera diversos problemas na manutenção, principalmente em aplicações maiores.

Com o grande sucesso da componentização no React, a forma de se escrever CSS vem mudando drasticamente.

A primeira revolução veio com o CSS Modules.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

A ideia é simples: escrever o mesmo CSS de sempre com apenas uma diferença: esse CSS só vai valer para aquele componente, ou seja, será um módulo (daí o nome, CSS Modules).

Segue um exemplo simples de uso do CSS Modules e o arquivo de estilos que só valerá para o componente acima:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

A segunda revolução veio com o styled-components.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Nele, o próprio componente já teria seus estilos escritos em JavaScript, sem que nenhum arquivo CSS fosse sequer criado. Uma das vantagens do styled-components é que o code-splitting fica muito mais fácil de ser feito e assim como o CSS Modules, não existe CSS global. A desvantagem é que você não escreve o CSS padrão, o qual muitos já estão acostumados, o que pode não ser muito intuitivo.

Um exemplo simples:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Bundlers

Resolver dependências no front-end, apesar de ser uma questão comum, sempre foi extremamente problemático.

Na maioria dos projetos temos que lidar, no mínimo, com essas questões:

  • A concatenação e minificação do JavaScript (ou TypeScript, ES2015, CoffeScript, etc) e do CSS (ou Sass, Less, Stylus etc)
  • Inclusão de Imagens
  • Adição de Fontes

 

Dessa necessidade frequente das aplicações front-end surgiram os module bundlers, e no mundo React o bundler mais usado pela comunidade é o Webpack.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

O Webpack também consegue prover, além de resolver todos os problemas acima (imagens, fontes e a minificação/concatenação de JavaScript e CSS):

 

Além de outras features também muito interessantes.

State containers

Para aplicações mais complexas, usar apenas o setState nativo do React pode não ser o suficiente para controlar toda a lógica da aplicação.

Existem diversos gerenciadores de estado feitos exclusivamente para lidar com esse problema, entre eles Flux, MobX, Reflux e o mais famoso deles, o Redux.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Dito isso, toda vez que tivermos que tomar uma decisão de adicionar uma nova biblioteca no projeto temos que pesar o custo/benefício dessa decisão. E para a grande maioria das aplicações que não são complexas o bastante nenhuma das opções acima (inclusive o Redux) são necessárias.

Me preocupa ver na comunidade diversos iniciantes começando a aprender o Redux antes mesmo de entender bem o próprio React ou até mesmo criando projetos já com o Redux, sem antes ter visto se há de fato uma necessidade.

O próprio criador do Redux já falou sobre isso:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Testes

Outro ponto crucial para o desenvolvimento de aplicações web é o uso de testes unitários. As garantias de que os testes nos dão são consideráveis. Podemos refatorar, encontrar e evitar novos bugs e até mesmo para escrever código a partir dos testes (TDD).

No mundo React, a principal ferramenta para escrever testes unitários é o Jest, mais um open source do Facebook.

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

O Jest tem três vantagens principais em relação aos concorrentes:

  • É extremamente fácil de configurar;
  • Vem com tudo o que você precisa para testar: o runner, as assertions, o report de coverage etc. Não é mais necessário instalar diversas bibliotecas diferentes para poder escrever testes unitários;
  • Snapshots.

 

Este último é tão interessante que vale a pena nos aprofundar um pouco mais. A ideia das Snapshots é simples: o Jest tira uma “foto” do seu componente e se algo mudar o teste vai quebrar e te avisar dessa mudança, mostrando exatamente como o componente era e como ele ficou.

E isso tudo com pouquíssimas linhas de código:

O GUIA COMPLETO DO REACT E O SEU ECOSSISTEMA

Conclusão

Para recapitular, neste post aprendemos as partes mais centrais do React como JSX, Virtual DOM, Lifecycle, Componentização, One-way data binding etc. Além disso, conhecemos também os principais atores que fazem parte do ecossistema do React, entre eles Webpack, create-react-app, Jest, CSS Modules etc.

Mas se mesmo assim ficou alguma dúvida, basta colocar nos comentários abaixo. ?

Este artigo foi postado originalmente em https://www.concrete.com.br/2017/07/26/o-guia-completo-do-react-e-o-seu-ecossistema/