No tutorial passado, começamos com a primeira parte de uma série de artigos sobre ReactJS para iniciantes. Aprendemos o que é e para que serve o ReactJS e sua relação com SPAs (Single Page Applications) e aprendemos a criar, entender e modificar ligeiramente um projeto inicial nesta fantástica tecnologia.
Para seguir acompanhando esta série, é importante que você tenha feito o passo-a-passo anterior, ou ao menos saiba criar um projeto ReactJS do zero, que é o que seguiremos utilizando aqui.
Vamos lá!
Entendendo os Componentes
Uma das coisas mais incríveis e talvez mais importantes que você deve saber sobre React é a como construir componentes. A componentização é o coração do React, permitindo atualizações parciais da página, reutilização de código e maior produtividade na manutenção do código de front-end. Com eles, podemos quebrar grandes e complexas aplicações em pequenos pedaços simples.
Basicamente, uma maneira de pensar em componentes é lidar de maneira semelhante ao que fazemos com micro serviços ou com classes. Nós agrupamos um trecho de código de modo que possamos utilizá-lo facilmente mais tarde, em todos os locais que ele for necessário. Sim, é uma explicação meio ruim, mas é mais ou menos isso que acontece com componentes em ReactJS.
Se eu tenho um cabeçalho/header que aparece em todas as páginas do meu site, porque não criar um componente para esse header e referenciá-lo em todos os locais em que precisamos dele? Pode dar um pouco mais de trabalho no início, na primeira vez, mas futuramente, quando tivermos que modificar algo no cabeçalho, o faremos apenas nesse componente e automaticamente todos os locais que o utilizam vão estar atualizados.
Outro exemplo é quando temos listas de resultados em uma pesquisa, principalmente de itens ricos de informações como anúncios de classificados. Geralmente neste caso temos o título do anúncio, uma imagem, dados do anúncio, link e muitos outros elementos. Esse “bloco” é repetido diversas vezes, uma para cada resultado, o que torna outro candidato forte a se tornar um componente quando usamos ReactJS.
E não é apenas uma questão de uniformidade na aparência, mas de conseguir trabalhar a lógica de interface de cada componente que compõem a interface de maneira isolada. Assim, toda a lógica para construção desse item acima (ele tem foto para exibir? O anunciante do anúncio está online? Ele teve seu preço reduzido?) fica dentro do próprio componente, mantendo a organização e facilitando a manutenção e testes.
Criando um componente
Para exercitar o conceito, vamos criar um primeiro componente bem simples, que vai representar o cabeçalho da nossa aplicação. Para fazer isso, crie um arquivo Header.js na pasta src da aplicação (a mesma onde tem o App.js) e aqui fica a primeira dica importante: tanto o nome do arquivo quanto a função que retornará o HTML desse componente devem ter a primeira letra maiúscula, para não se confundir com os componentes HTML padrões.
Todo componente deve conter em seu interior a função que constrói o HTML do mesmo e o export da mesma, como no exemplo abaixo:
1 2 3 4 5 6 7 8 9 10 11 |
function Header() { return ( <header> <h1>Header Component</h1> </header> ); } export default Header; |
Note como neste exemplo simples, minha função Header apenas retorna o HTML que queremos que seja renderizado onde este componente foi usado e isso é uma coisa muito bacana do ReactJS moderno, que torna muito prático o uso de HTML em conjunto com JS.
Mas e agora, como usamos este componente na nossa aplicação?
É muito fácil. Para isso, basta voltarmos até o nosso App.js e primeiramente, adicionarmos um import do nosso componente recém-criado, como abaixo (vou repetir os demais imports do arquivo apenas para você conseguir se localizar).
1 2 3 4 5 |
import logo from './logo.svg'; import './App.css'; import Header from './Header'; |
E onde queremos que o Header seja renderizado na nossa função de retorno, usaremos uma tag com o mesmo nome do componente. Por isso é importante que os nomes dos nossos componentes sejam com a primeira letra maiúscula, pois isso irá ajudar a diferenciar das tags HTML comuns.
1 2 3 4 5 6 7 8 9 10 |
function App() { return ( <div className="App"> <Header /> <img src={logo} className="App-logo" alt="logo" /> </div> ); } |
O resultado, é a junção do HTML do Header.js (o H1) com o do App.js (imagem) e o resultado você consegue ver abaixo (se não estiver rodando na sua máquina, lembre-se de executar “npm start” no terminal, dentro da pasta do projeto).
E agora, como o Header é um componente, experimente replicar a tag dele diversas vezes dentro da função App para ver que ele se multiplicará na tela da aplicação.
Parametrizando um componente
Outro conceito importante de componentes em React é parametrização. Quando usamos um mesmo componente em diferentes partes da nossa aplicação, podemos configurar ele passando parâmetros ao mesmo, da mesma forma que faríamos com tags HTML comuns.
Mas para que isso seja possível, devemos modificar a nossa função Header para que ela espere um objeto de propriedades e, a partir desse objeto, pegamos as informações que queremos e as juntamos ao HTML usando chaves {}.
1 2 3 4 5 6 7 8 9 10 11 |
function Header(props) { return ( <header> <h1>{props.title}</h1> </header> ); } export default Header; |
No exemplo acima, estaremos esperando as propriedades do componente como parâmetro da função e usamos somente uma propriedade hipotética title (entre chaves, para ocorrer o evaluation da propriedade) para tornar o H1 do componente configurável.
Mas como que passamos essa configuração?
Da mesma maneira que faríamos com HTML comum, diretamente onde chamamos a tag Header no módulo App.js.
1 2 3 4 5 6 7 8 9 10 |
function App() { return ( <div className="App"> <Header title="Header Param" /> <img src={logo} className="App-logo" alt="logo" /> </div> ); } |
O resultado é que o título renderizado na página agora é modificado de acordo com a propriedade title da tag Header.
Agora experimente colocar várias vezes o componente Header na sua App.js, apenas mudando o title entre eles, para ver o que acontece.
Esse é o poder de componentes parametrizados!
Atenção: devido a essa possibilidade de criar propriedades/parâmetros personalizados para tags, existem algumas pequenas diferenças em relação ao HTML tradicional, como por exemplo a propriedade class, onde você colocaria a classe CSS, certo? No ReactJS, devemos usar className pois class é uma palavra reservada em JavaScript.
Estados do componente
Outro conceito muito importante de aprender antes que possamos de fato começar a construir aplicações em ReactJS é o conceito de Estados. Você aprender sobre eles seguindo o tutorial, ou optando pelo vídeo abaixo, que também fala sobre eles.
Estados são a forma como o ReactJS permite que os componentes mantenham informações alteradas/controladas pelo usuário na interface. Por exemplo, e se quisermos alterar um contador a cada clique de um botão? Para conseguirmos fazer isso precisamos manter o estado desse contador entre um clique e outro, certo?
Para fazer isso, vamos modificar o nosso App.js para criar uma variável de contagem e imprimi-la na tela.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function App() { let contador = 0; return ( <div className="App"> <Header title="Header Param" /> <img src={logo} className="App-logo" alt="logo" /> <p>{contador}</p> cliques! </div> ); } |
Se você olhar lá na aplicação (se ela não tiver atualizado sozinha, basta um F5 no navegador) verá que está marcando 0 cliques. Isso mostra como podemos imprimir uma variável local na interface.
Para colocar um botão, mesmo que ainda sem comportamento, basta inserir o HTML do botão junto às demais tags do return do App() e não é isso que eu espero lhe ensinar aqui, mas como vincular uma function com a lógica do clique do botão à ele, para que atualize o contador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function App() { let contador = 0; function increment(){ contador++; console.log(contador); } return ( <div className="App"> <Header title="Header Param" /> <img src={logo} className="App-logo" alt="logo" /> <p> <input type="button" value="Clique" onClick={increment} /> </p> <p>{contador}</p> cliques! </div> ); } |
O código acima mostra o HTML do botão e como associar o onClick dele a uma function JavaScript definido dentro da App (sim, é uma function dentro de outra function, não se preocupe). Se você executar esse código, verá que ele imprime o contador incrementalmente a cada clique no console, mas que na interface, ele não está mudando o contador impresso.
Isso porque ainda não estamos usando estados!
Para usar estados, primeiro precisamos adicionar um import da lib do React, o useState, como abaixo.
1 2 3 |
import {useState} from 'react'; |
Depois, poderemos usar essa function useState para armazenar estados da nossa aplicação ao invés de armazenar variáveis comuns. Isso vem com um pró e um contra. A vantagem é obviamente o fato de manter a nossa interface plugada na nossa lógica de front-end. A desvantagem é referente ao conceito de imutabilidade.
Todo estado é imutável em React, isso quer dizer que não podemos manipular um estado já existente, mas ao invés disso, nós temos de usar uma função para criar um novo estado sobre o antigo. Isso é feito usando a function useState que importamos agora há pouco, quando chamada (passando o valor inicial do estado) retorna um array com duas posições: na primeira, o valor atual do estado, na segunda, a função que “altera” o mesmo.
1 2 3 4 5 6 |
const [contador, setContador] = useState(0); function increment(){ setContador(contador+1); } |
No código acima, eu não declaro mais uma variável contador simples, mas carrego um contador e uma função de mudança de estado usando o useState e passando a ele o valor inicial do estado (0 neste caso), utilizando as duas na function de increment.
Com isso, já temos o nosso “click and increment” funcionando!
Uma dica para quem quer trabalhar bem forte o conceito de componentes de UI em ReactJS é dar uma estudada em React Storybook, uma ferramenta que ajuda na criação, testes e na organização do design system da aplicação.
E com isso, nós encerramos esta segunda parte da nossa série sobre ReactJS para Iniciantes e com o conteúdo dessa aula abre-se um universo de possibilidades pois já conseguimos ter uma aplicação web dinâmica, então clica nesse link e acessa a terceira parte da série!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.