O que estamos construindo

Neste tutorial do React para iniciantes, vamos construir um aplicativo de compras. Trabalharemos com objetos de estado complexos, atualizaremos partes do estado e usaremos o estado existente para calcular o novo estado.

Confira aqui:

project

Tente você mesmo

Se você quiser experimentar primeiro, aqui estão os cenários (você também pode pegar o código inicial abaixo):

  • O usuário deve ser capaz de adicionar novos itens à lista, digitando na entrada e clicando no símbolo “+”
  • O usuário deve ser capaz de aumentar / diminuir as quantidades de um determinado item
  • O total deve mostrar a quantidade total de todos os itens da lista

Passo a passo de vídeo

Código Inicial

Acesse no GitHub aqui

Como exibir uma lista de itens

A primeira coisa que faremos é exibir uma lista de itens. Se você estiver trabalhando com o código inicial, verá que adicionei um objeto de estado:

const [items, setItems] = useState([]);

Vamos inicializar isso com uma série de objetos. Em seguida, usaremos a função map para percorrer essa lista e exibir os itens.

Substitua a linha acima pelo seguinte:

const [items, setItems] = useState([	{ itemName: 'item 1', quantity: 1, isSelected: false },	{ itemName: 'item 2', quantity: 3, isSelected: true },	{ itemName: 'item 3', quantity: 2, isSelected: false },]);

Você notará que cada item da matriz é um objeto. Este objeto representa cada item (ou linha) e contém as coisas que precisaremos exibir:

  • O nome do item
  • A quantidade
  • Uma bandeira que usaremos para exibir um “tique” ou “círculo vazio”

A razão pela qual colocamos esta lista no estado como um array é porque a lista mudará. Quando queremos alterar a lista, apenas adicionamos ou removemos do array e o React atualizará automaticamente a IU para nós.

Ok, agora só temos que adicionar uma função de mapa ao nosso JSX e fazer um loop sobre esse array e exibir as propriedades na IU.

Substitua o lista de itens div com o seguinte:

<div className="item-list">	{items.map((item, index) => (		<div className="item-container">			<div className="item-name">				{item.isSelected ? (					<>						<FontAwesomeIcon icon={faCheckCircle} />						<span className="completed">{item.itemName}</span>					</>				) : (					<>						<FontAwesomeIcon icon={faCircle} />						<span>{item.itemName}</span>					</>				)}			</div>			<div className="quantity">				<button>					<FontAwesomeIcon icon={faChevronLeft} />				</button>				<span> {item.quantity} </span>				<button>					<FontAwesomeIcon icon={faChevronRight} />				</button>			</div>		</div>	))}</div>

Vamos examinar isso.

  • Introduzimos a função de mapa. Ele fará um loop sobre os itens no Itens array e exibe um monte de JSX para cada item. Lembre-se, a função de mapa nos dá o objeto atual está atualmente ligado como uma variável para que possamos acessar suas propriedades.

  • Estamos usando um ternário para verificar o item.isSelected variável. Se a variável for verdadeira, exibimos um “tique” tachado. Se o valor for falso, exibimos um “círculo vazio” junto com o nome do item.

  • Também estamos exibindo a quantidade desse item específico.

Como armazenar o que o usuário digita no estado

Agora que temos alguns itens sendo exibidos, permitiremos que o usuário adicione alguns itens à lista. Não seria uma lista de compras muito boa se eles não pudessem adicionar coisas a ela!

Você verá no código inicial que incluí uma entrada:

<div className="add-item-box">	<input className="add-item-input" placeholder="Add an item..." />	<FontAwesomeIcon icon={faPlus} /></div>

No momento, isso não faz muito. Precisamos dar controle ao React para que possamos trabalhar facilmente com o valor que o usuário digitou.

Para fazer isso, criaremos um novo valor de estado para conter o valor que o usuário digitou e adicionaremos um evento onChange para alterar este valor.

Adicione um novo objeto de estado e inicialize-o com uma string vazia:

const [inputValue, setInputValue] = useState('');

Agora, na entrada, adicione um valor e um em mudança funcionar assim:

<input value={inputValue} onChange={(event) => setInputValue(event.target.value)} className="add-item-input" placeholder="Add an item..." />

Sempre que o usuário digita, o em mudança evento é chamado. React passa no evento automaticamente para nós, para que possamos obter o valor que o usuário digitou a partir disso.

Em seguida, pegamos esse valor e chamamos o setInputValue para definir o que o usuário digitou no estado.

Em seguida, definimos o valor da entrada para qualquer valor armazenado no valor de entrada Estado variável.

Como adicionar um novo item à lista

Agora faz sentido adicionar o valor que o usuário digitou à lista. Como conhecemos a lista atual e sabemos o que o usuário digitou (colocamos tudo no estado!), Tudo o que temos que fazer é misturar essas coisas.

Em outras palavras, vamos adicionar o valor de entrada ao Itens array.

Comece criando uma nova função, que será chamada quando o usuário clicar no ícone “+”:

const handleAddButtonClick = () => {	const newItem = {		itemName: inputValue,		quantity: 1,		isSelected: false,	};	const newItems = [...items, newItem];	setItems(newItems);	setInputValue('');};

O que isso é:

  • Cria um novo objeto chamado novo item que é o que é enviado ao array. Nós definimos o nome do item para qualquer que seja o valor de entrada é, nós assumimos o padrão quantidade para 1, e o padrão é selecionado booleano para falso

  • Copia a matriz existente (fazemos isso para evitar a mutação do estado) e adiciona nosso objeto newItem até o fim

  • Empurra a nova matriz de volta ao estado

  • Finalmente, redefine o valor de entrada para esvaziar a string para que o usuário possa digitar e adicionar mais coisas

Agora que temos uma função, só precisamos conectá-la ao nosso botão:

<FontAwesomeIcon icon={faPlus} onClick={() => handleAddButtonClick()} />

Se você executar o código, digite coisas na entrada e clique no ícone “mais”, ele deve ser adicionado à lista. Woohooo!

Como alternar um item

Agora veremos como podemos alternar um item para indicar que ele foi selecionado. Sabemos que cada item na matriz / lista tem um *é selecionado variável, então tudo o que temos que fazer é atualizá-la quando um item é clicado.

Crie uma nova função como esta:

const toggleComplete = (index) => {	const newItems = [...items];	newItems[index].isSelected = !newItems[index].isSelected;	setItems(newItems);};

Isso leva um índice como um parementer. O índice é fornecido pela função de mapa e indica o que posição na matriz em que estamos atualmente.

Em seguida, usamos este índice para obter o objeto da matriz e definir o é selecionado variável ao oposto do que é atualmente.

Em seguida, colocamos os itens atualizados no estado. Isso faz com que o React renderize novamente o componente e renderize um “círculo marcado” ou um “círculo vazio” para cada item, dependendo do sinalizador this (lembre-se de que escrevemos a lógica do ternery para isso anteriormente).

Para fazer tudo funcionar, só precisamos ligar toggleComplete quando o usuário clica no círculo:

Atualize o nome do item div assim:

<div className="item-name" onClick={() => toggleComplete(index)}>	// ...other code</div>

Observe que passamos o índice que obtemos da função de mapa. Isso nos diz a posição atual na matriz em que estamos.

Execute o código e você poderá “selecionar” um item. Sucesso!

Como atualizar as quantidades

Faremos uma abordagem semelhante para atualizar as quantidades. Começaremos com o aumento da quantidade. Adicione uma função como esta:

const handleQuantityIncrease = (index) => {	const newItems = [...items];	newItems[index].quantity++;	setItems(newItems);};

Você notará que isso é semelhante ao toggleComplete função:

  • Usamos o índice para obter o item / objeto da matriz
  • Nós aumentamos a quantidade
  • Colocamos tudo de volta no estado

Agora só precisamos atualizar nosso botão para chamar esta função:

<button>	<FontAwesomeIcon icon={faChevronRight} onClick={() => handleQuantityIncrease(index)} /></button>

Tente fazer isso e você conseguirá clicar na “divisa certa” e a quantidade deverá aumentar.

Lidando com o diminuir quantidade será semelhante novamente. Crie uma função como esta:

const handleQuantityDecrease = (index) => {	const newItems = [...items];	newItems[index].quantity--;	setItems(newItems);};

O que estamos fazendo:

  • Usamos o índice para obter o item / objeto da matriz
  • Nós diminuímos a quantidade
  • Colocamos tudo de volta no estado

Como calcular a quantidade total

Ok, nosso aplicativo está com boa aparência. A última coisa que precisamos fazer é atualizar a quantidade total na parte inferior.

A primeira coisa que faremos é criar um valor de estado. Isso será usado para reter / exibir as quantidades totais:

const [totalItemCount, setTotalItemCount] = useState(6);

Vamos usar como padrão 6 pois isso é o que as quantidades na lista inicial somam.

A seguir, vamos renderizar isso em nosso JSX:

<div className="total">Total: {totalItemCount}</div>

Tudo parecerá igual até agora. Isso porque ainda não escrevemos nenhuma lógica para atualizar o estado. Vamos criar uma nova função:

const calculateTotal = () => {	const totalItemCount = items.reduce((total, item) => {		return total + item.quantity;	}, 0);	setTotalItemCount(totalItemCount);};

Isso usa o reduzir função para somar todas as quantidades em nossa matriz de itens.

Por último, tudo o que temos que fazer é chamar esta função sempre que o usuário aumentar / diminuir a quantidade ou adicionar um novo item. Atualize as respectivas funções da seguinte forma:

	const handleAddButtonClick = () => {    // ...other code		calculateTotal();	};	const handleQuantityIncrease = (index) => {    // ...other code		calculateTotal();	};	const handleQuantityDecrease = (index) => {    // ...other code		calculateTotal();	};

Vá em frente e tente aumentar / diminuir as quantidades. Você notará que a quantidade total também muda!

Quer mais ideias de projetos?

Por que não tentar construir alguns projetos React para impulsionar ainda mais seu aprendizado?

Toda semana eu envio um novo projeto para você experimentar um exemplo prático, código inicial e dicas. Inscreva-se para receber isso diretamente na sua caixa de entrada!



Fonte