Você já deve ter ouvido falar do React, a biblioteca JS mais popular da atualidade, usado por várias empresas grandes como Facebook, Airbnb e Twitter. A ideia desse artigo é demonstrar a criação de uma aplicação simples, que use as principais partes do React. Neste tutorial nós iremos ver:
- Componentes
- Componentes puros/funcionais
- O uso do state vs props
Todos os exemplos deste tutorial serão escritos em ES6. Se você não sabe ES6 leia esse artigo antes. Se você é impaciente demais para isso considere que:
ES6:
ES5:
ES6:
ES5:
ES6:
ES5:
Outro pré-requisito para o tutorial é ter o Node.js instalado na sua máquina. Se você ainda não fez isso, clique aqui e siga as instruções, dependendo do seu sistema operacional.
Afinal, o que é React?
React é uma biblioteca criada pelo Facebook em 2013 com o objetivo de tornar o desenvolvimento de Single Page Applications (SPAs) mais fácil. A biblioteca se baseia em alguns conceitos como:
Componentes
Uma aplicação React é dividida em componentes, ou seja, pequenos pedaços de código responsáveis por alguma parte da UI. Um componente ideal é independente e reutilizável, capaz de retornar a resposta esperada usando apenas dados genéricos enviados por outras partes da aplicação.
Um exemplo de componente React interessante pode ser visto nessa biblioteca de mapas:
Graças ao componentes do React, podemos importar um mapa do Google Maps e usá-lo como se fosse uma tag nativa de HTML, passando apenas as propriedades que nós queremos no componente, como defaultZoom e defaultCenter.
JSX
Em React nós não usamos HTML, toda a marcação é feita no JavaScript, com uma sintaxe baseada em XML chamada JSX. A ideia pode parecer bem maluca no começo mas vai fazer sentido assim que você começar a escrever os seus próprios componentes. JSX parece bastante com HTML mas existem algumas diferenças como:
-
Todas as tags devem ser fechadas
-
Podemos colocar expressões JavaScript dentro do JSX usando {}. Ex.: function ola() {
return “ola”;
}{2 + 2}
{ola()}
-
Como o JSX fica dentro de arquivos ‘.js’ a palavra class não pode ser usada. Em seu lugar, devemos usar className. Ex.:
Olá!
Por debaixo dos panos, usamos o Babel para converter o JSX em funções comuns de JavaScript, logo, esse código:
Fica assim:
Leia mais sobre JSX aqui.
Virtual DOM
Para evitar updates custosos e desnecessários, o React não escreve as alterações diretamente na DOM. Ao invés disso, a biblioteca cria uma cópia da árvore de componentes em memória e esta cópia (Virtual DOM) é quem recebe os updates primeiro. Depois que a Virtual DOM é atualizada o React calcula a maneira mais eficiente de atualizar a árvore DOM real usando um algoritmo de diffing.
Pondo a mão na massa
Ok, chega de tanta teoria, vamos por a mão na massa! Abra o seu terminal e vamos instalar um pacote que vai nos ajudar a criar nossas aplicações o create-react-app:
Montar um ambiente de desenvolvimento capaz de suportar React costumava ser uma tarefa complicada (esse tutorial do Diego Eis explica muito bem a criação de um ambiente “na mão”). Por causa disso, o Facebook inventou um pacote chamado create-react-app, que cria um ambiente com tudo o que nós precisamos para começar o nosso projeto (React, ES6 e webpack).
Depois de instalar o pacote, vamos criar um novo projeto. No terminal digite:
Depois de alguns minutos todas as dependências estão instaladas e voilà! Temos um projeto pronto para ser criado.
Com o terminal do diretório do seu projeto digite:
Se tudo deu certo, o seu browser em https://localhost:3000/ deve estar assim:
Parabéns! Você acabou de criar a sua primeira aplicação com React! Vamos dar uma olhada no que foi gerado:
Como podemos ver, a pastar src contém todos os nosso componentes React. Dentro de src abra o arquivo index.js, ele deve conter algo desse tipo:
O index.js é o arquivo principal da nossa aplicação, ele é responsável por colocar o nosso componente principal (App) no elemento root da nossa página. Root é uma div que está dentro do único arquivo .html do projeto (public/index.html). Toda a nossa aplicação vai ser escrita dentro dessa div root.
Criando nosso primeiro componente
Abra o arquivo App.js, ele é o primeiro componente da nossa árvore. Dentro dele podemos ver o JSX usado para renderizar a tela de boas vindas do create-react-app:
Note que todo esse código está dentro de um método chamado render na classe App que é filha da classe de React.Component. Render é responsável por dizer ao React o que deve ser renderizado, todo componente precisa de um método render para exibir alguma coisa.
Substitua o método render por:
Se tentarmos rodar o projeto, veremos o seguinte erro:
Isso acontece porque estamos tentando usar um component (HelloWorld) que ainda não foi definido. Vamos resolver isso criando um arquivo chamado HelloWorld.js dentro da pastar src. Dentro de HelloWorld coloque:
Esse código cria um componente React chamado HelloWorld e implementa o método render que retorna um parágrafo com olá mundo. Depois disso vamos importar nosso novo componente em App.js:
Agora abrindo o browser em https://localhost:3000/ vemos:
Ótimo! Nós acabamos de criar nosso primeiro React Component o/. Mas ele não faz lá muita coisa não é mesmo? Vamos tentar fazer esse componente ser mais customizável.
E se nós quiséssemos exibir o nome de uma pessoa na mensagem do nosso HelloWorld? Obviamente poderíamos fazer algo do tipo:
Mas e se for necessário escrever novos nomes? Criar um componente novo para cada pessoa não parece uma ideia muito inteligente… lembra do exemplo do Google Maps mostrado na introdução? No exemplo, nós passávamos dados para um componente como se fosse uma tag HTML. Vamos fazer a mesma coisa para o nosso HelloWorld! Mude App.js para:
Veja que dessa vez nós tivemos que colocar o HelloWorld dentro de uma div, isso acontece porque o método render deve sempre retornar apenas um elemento, sempre que tiver que renderizar mais de um elemento no seu componente, coloque tudo dentro de uma div.
Agora nós temos que fazer com que o componente HelloWorld leia o valor dado em nome. Isso pode ser feito facilmente usando o objeto props presente em todo componente React. Veja como HelloWorld.js vai ficar agora:
Tudo que for passado de um componente para outro é adicionado ao objeto props, podendo ser acessado dentro do componente. Nós também usamos a propriedade propTypes para informar ao React que a prop ‘nome’ é uma string e que essa string é obrigatória para o funcionamento do componente (isRequired). Você não é obrigado a usar propTypes nos seus componentes, mas é interessante fazer isso, já que elas facilitam a documentação do seu código e podem reduzir erros.
Agora nós temos um componente muito mais genérico:
Props são algo crucial para os componentes React, já que com elas nós podemos fazer com que o nosso componente seja reutilizado até mesmo em outra aplicação. Mas devemos sempre ter em mente que props são imutáveis, uma vez definida a prop ‘nome’, uma instância de HelloWorld não pode mais ser alterada. Ex.:
Componente “puro” ou stateless
Nosso componente HelloWorld é bastante simples e utiliza apenas props, por causa disso ele pode ser escrito de uma forma melhor, utilizando uma função pura. Veja como fica o nosso componente em forma de função:
Veja que dessa vez o componente é basicamente escrito em apenas uma linha (const HelloWorld = (props) => Olá {props.nome}!;). Esse é o React Component ideal! Simples, reutilizável e escrito em apenas uma função! Tente criar seus componentes dessa maneira, ao invés de ter um componente complexo e grande, crie vários componentes menores e simples, isso vai melhorar bastante a qualidade do seu projeto.
Para comprovar que o nosso componente é realmente reutilizável vamos usá-lo em uma lista de nomes. Volte para App.js e digite:
Perceba que nós temos uma mudança aqui, para exibir nomes do nosso array nós usamos a função map, já que ela retorna uma expressão JavaScript (além de ter uma sintaxe mais legal que a do o laço for :P) e passamos uma nova prop chamada key para o nosso componente. Keys ajudam o React a identificar qual elemento foi adicionado/removido de uma lista/array (mais informações sobre o assunto aqui). Uma Key deve sempre ser um valor único ou poderemos ter problemas de performance. Evite usar o índice do seu loop como key em aplicações reais (como fizemos no exemplo acima), tente usar números realmente únicos como um ID vindo de um backend. Leia mais sobre isso aqui.
Como visto anteriormente props são imutáveis, componentes feitos apenas com props não podem por exemplo, ser atualizados baseados em uma ordem do usuário. Para representar o estado mutável do seu componente usamos a propriedade state.
Para ilustrar o uso de state no nosso elemento vamos fazer um novo componente e chamá-lo de ContaClick.js:
No construtor da classe ContaClick nós definimos o estado inicial do nosso componente: um contador de clicks que começa em 0. Vamos adicionar um botão para atualizar o contador:
No código acima nós criamos um botão embaixo do exibidor de cliques que chama o método clicou sempre que o evento onClick é disparado. O método clicou substitui o objeto state do componente ContaClick por um objeto novo com clicks incrementados em uma unidade. Veja que nós atualizamos o state usando a função setState. NUNCA atualize o objeto state manualmente.
Agora vamos colocar o nosso componente ContaClick em app:
Pronto! Rodando a aplicação podemos usar o contador e ver que ele é atualizado a cada clique!
Até a próxima!