Com a chegada dos Hooks ao React, se tornou possível a criação de coisas que antes eram exclusivas de componentes baseados em classes. Um dos Hooks mais populares (a talvez o mais importante) é o useState. Nesse artigo, eu vou te ensinar a criar um projeto simples para demonstrar como é a utilização do useState na prática.

Para essa incrível jornada eu vou utilizar o Visual Studio Code, juntamente com os obrigatórios Node, npm (ou yarn) e a versão mais recente do React (no meu caso, v16.13.1). Vamos lá!

Primeiros Passos

Para criação do projeto, eu vou utilizar o comando create-react-app no terminal. Como o projeto consiste em uma simples lista de compras, chamarei ele de list.

npx create-react-app list

Concluído o processo de criação e instalação, será criada uma estrutura de pastas semelhante a esta:

Se quiser, você pode apagar os arquivos App.test.js, logo.svg e setupTests.js, pois eles não serão utilizados nesse projeto.

Código Base

Primeiramente, vamos para o arquivo App.js. É lá que a mágica vai acontecer. Apague todo o conteúdo e deixe apenas o seguinte:

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <h1>Lista de Compras</h1>
    </div>
  );
}

export default App;

Agora vamos adicionar alguns elementos para formar o projeto. Adcione um input para receber o nome dos itens que serão adicionados na lista de compras. E, adcione um botão que servirá para incluir o item.

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <h1>Lista de Compras</h1>
      <input type="text" placeholder="Item"/>
      <button>Adicionar Item</button>
    </div>
  );
}

export default App;

Ainda está bem simples. Vamos aplicar alguns estilos antes de prosseguir. Para isso usaremos o arquivo de estilização do App.js, o App.css. Esse arquivo possui alguns dados desnecessários, então recomendo que você faça uma limpeza e deixe apenas o essencial para estilizar:

.App {
  text-align: center;

}

html {
  color: #fff;
  background-color: #282c34;
}

ul {
  list-style-type: none;
}

li {
  font: 200 20px/1.5 Helvetica, Verdana, sans-serif;
  border-bottom: 1px solid #ccc;
}

Se dermos uma olhada no projeto rodando, ele estará assim:

Simples, mas vai cumprir o seu papel muito bem.

UseState

Agora, importe o useState para que posa usá-lo. No arquivo App.js, adicione o seguinte ao import do React:

import React, { useState } from 'react';

Agora sim podemos usar o useState, adicionando o seguinte trecho:

const [item, setItem] = useState('');

Esse Hook tem uma estrutura de declaração simples, com apenas dois elementos. No meu caso, o item e o setItem.

O item é o estado em si. Enquanto o setItem é a função que permite modificar o item. Semelhante ao setState. Nesse exemplo, o item foi declarado para ser inicializado como uma String vazia.

O próximo desafio é fazer o input funcionar com o useState, para que, na medida que formos digitando, ele funcione normalmente. É bem simples:

<input type="text" placeholder="Item" value={item} name="item" onChange = {e => setItem(e.target.value)} />

Como queremos atualizar o valor no estado (item) a medida que for sendo digitado no campo de texto, precisamos chamar a função que vai realizar as alterações nele (setItem). Para isso, vamos usar o onChange, passando apenas um evento, juntamente com o valor que está armazenado no input.

Até agora, o código deve estar assim:

import React, { useState } from 'react';
import './App.css';

function App() {

  const [item, setItem] = useState('');

  return (
    <div className="App">
      <h1>Lista de Compras</h1>
      <input type="text" placeholder="Item" value={item} name="item" onChange = {e => setItem(e.target.value)} />
      <button>Adicionar Item</button>
    </div>
  );
}

export default App;

O próximo passo é adicionar produtos na lista de compras. Para isso precisamos de duas coisas:

  • Um outro estado capaz de armazenar uma lista
  • Uma função que consiga adicionar o valor à lista

Criar outro estado vai ser moleza, é só fazer o seguinte:

const [itemList, setItemList] = useState([])

Temos o itemList com o setItemList. Seu valor inicial será um Array vazio. Assim poderemos adicionar múltiplos itens aqui.

A função que adiciona itens também é simples. Será inserido um valor dentro de um Array, com algumas mudanças:

const addItem = () => {
    setItemList([item].concat(itemList))
    setItem('')
}

Chamei a função de addItem. Para funcionar, é preciso invocar o setItemList, passando como parâmetro o valor que queremos inserir na lista – nesse caso, esse valor é o item. E, a função concat, dizendo a qual Array aquele valor será adicionado (itemList). A função push em si não dá certo, precisa ser a concat.. Por fim, zerei o valor que estava dentro do item, para que o campo seja automaticamente limpo sempre que um item for adicionado.

É preciso garantir que essa função será chamada sempre que clicarmos no botão Adicionar Item. Para isso criaremos um evento onClick, com a referência do addItem:

<button onClick={addItem}>Adicionar Item</button>

Adicionar Item

Chegamos na última parte do projeto! Aqui vamos criar e renderizar a lista de itens que serão inseridos. Para isso você deve criar a seguinte estrutura de listas:

return (
    <div className="App">
      <h1>Lista de Compras</h1>
      <input type="text" placeholder="Item" value={item} name="item" onChange = {e => setItem(e.target.value)} />
      <button onClick={addItem}>Adicionar Item</button>
      <ul>
        <li>Teste</li>
      </ul>
    </div>
);

Ela está estática, e não é isso o que queremos. É preciso que tudo o que for digitado no input acima seja adicionado à lista. É preciso fazer algum tipo de laço dentro da lista de itens que foram adicionadas ao nosso Array (itemList) e que a cada repetição do laço seja criada uma nova linha na lista com o valor. É possível fazer isso usando o map:

return (
    <div className="App">
      <h1>Lista de Compras</h1>
      <input type="text" placeholder="Item" value={item} name="item" onChange = {e => setItem(e.target.value)} />
      <button onClick={addItem}>Adicionar Item</button>
      <ul>
        {itemList.map((item) => (
          <li>{item}</li>
        ))}
      </ul>
    </div>
);

Esse laço vai percorrer o itemList com uma variável chamada item. Dessa forma, vamos renderizar todos os itens que estão dentro do Array, fazendo com que sejam mostrados como linhas da lista. O resultado é algo parecido com isso:

Considerações Finais

Nosso mini projeto está pronto. Como esperado, é algo simples que serviu para te ensinar como podemos utilizar essa ferramenta extremamente útil e popular dentro do desenvolvimento com React: o Hook de useState.

Espero que tenha entendido. Bons estudos!

Referências