Como criar uma lista de tarefas com React

Oi, pessoal!

Agora que já exploramos um pouco sobre o funcionamento de componentes com Reactjs, vamos desenvolver juntos uma aplicação simples para Lista de Tarefas.

Introdução

Neste artigo faremos um guia detalhado passo a passo para criar uma aplicação de Lista de Tarefa utilizando React e TypeScript como no exemplo da imagem acima.

O código deste projeto completo está disponível no github neste link.

A gestão de tarefas é uma funcionalidade fundamental em muitos projetos, e aprender a implementá-la de forma eficiente usando tecnologias modernas pode ser uma experiência enriquecedora para desenvolvedores iniciantes.

Por isso, abaixo você irá acompanhar na integra todas as etapas desse desenvolvimento.

Importações e definição da Interface

Levando em consideração que você já está por dentro dos conteúdos anteriores e já instalou as dependências do projeto, a primeira parte seria criar um arquivo tsx para receber nosso código e, dentro dele realizar as importações e criar a interface.

Vamos começar importando as funções React e useState de ‘react’. Além disso, iremos definir uma interface chamada Item, que representa a estrutura de cada item na lista de tarefas, com as propriedades id, texto e feito.

import React, { useState } from 'react';

interface Item {
  id: number;
  texto: string;
  feito: boolean;
}

Criando o Componente Lista de Tarefas

Perceba que dentro desta aplicação (abaixo), eu apenas criei um arquivo chamado TodoList dentro da pasta src e dentro dele vou adicionar uma função chamada TodoList, definida como um componente funcional que retorna um elemento JSX.

// src/TodoList.tsx

function Todolist(): JSX.Element {
// ...
}

export default Todolist;

Este arquivo deve ser exportado para que eu possa chamá-lo dentro do componente App, que será responsável pela renderização da página, veja como fica abaixo.

import TodoList from "./TodoList"

function App() {
  return (
    <div className="App">
      <TodoList />
    </div>
  )
}

export default App

Agora que já criamos o nosso componente TodoList e o importamos dentro do componente App, o próximo passo será criar o estado inicial da aplicação.

Estados da Lista de Tarefas

Estado Inicial

Na próxima etapa de nosso código é possível notar que utilizamos o hook useState.

const [tarefas, setTarefas] = useState<Item[]>([
  { id: 1, texto: 'Ir ao supermercado', feito: false },
  { id: 2, texto: 'Malhar', feito: false },
  { id: 3, texto: 'Estudar React', feito: false },
]);

Neste caso, utilizaremos a const [tarefas, setTarefas] para definir uma constante que chama tarefas e ela será responsável para armazenamento de um estado no componente. Toda vez que quisermos atualizar o estado criado precisaremos utilizar a função setTarefas.

Dentro do useState<Item[]>(...), utilizamos o hook useState do React para criar um estado inicial. O estado inicial é um array de objetos do tipo Item[]. O tipo Item no nosso caso seria a tarefa a ser realizada.

Dentro de nosso useState temos um array que contém três objetos, cada um representando uma tarefa. Cada objeto tem as seguintes propriedades:

  • id: Um número que identifica unicamente cada tarefa.
  • texto: Uma string que contém a descrição da tarefa.
  • feito: Um booleano que indica se a tarefa foi concluída ou não (inicialmente, todas as tarefas estão marcadas como não concluídas, ou seja, feito: false).

Portanto, o estado inicial representa uma lista de tarefas com três itens, onde cada item é um objeto com uma estrutura específica (id, texto, feito).

Esse estado será utilizado em um componente React para renderizar e manipular a lista de tarefas. A função setTarefas será usada para atualizar o estado das tarefas, por exemplo, marcando uma tarefa como concluída.

Estado Input

A const [input, setInput] será responsável por receber as respostas do usuário. Em nossa aplicação, esse será o local onde receberemos as tarefas adicionadas à lista de tarefas pelo usuário.

const [input, setInput] = useState<string>('');

Função para Alternar o Estado

Acredito que já tenham percebido que na nossa lista de tarefas, nós temos atividades feitas e não feitas. Por isso, a função abaixo é utilizada para alterar o estado de uma tarefa específica, invertendo o valor da propriedade feito (se a tarefa estava marcada como feita, passa a estar não feita e vice-versa) com base no id fornecido como argumento.

const alterarToggle = (id: number): void => {
  setTarefas((prevTarefas) =>
    prevTarefas.map((tarefa) =>
      tarefa.id === id ? { ...tarefa, feito: !tarefa.feito } : tarefa
    )
  );
};

Ao determinar o parametro como id:number estamos dizendo que esperamos receber um argumento do tipo numérico que representará a identificação de uma tarefa.

A utilização do : void => indica que a função não retorna nenhum valor (void).

Agora que já definimos nosso parametro e determinamos que a função não poderá retornar nenhum valor (void), precisamos determinar as tarefas setTarefas((prevTarefas) =>.

A função setTarefas recebe uma função como argumento. Essa função parece ser uma função de atualização do estado, onde prevTarefas representa o estado anterior das tarefas.

Depois disso é preciso utilizar a higher order function map para entrar dentro do estado com as tarefas anteriores(prevTarefas) e retornar um array novo com as modificações necessárias.

O último passo dessa função responsável por alterar o estado engloba o uso do ternário para verificar se o id da tarefa atual é igual ao id passado como argumento. Se for verdadeiro, cria um novo objeto (uma cópia da tarefa atual) com a propriedade feito invertida (o valor booleano negado). Se for falso, simplesmente retorna a tarefa sem modificações.

A utilização do ponto de exclamação ! significa dizer que estou invertendo toda a função/objeto atrelado a ele.

Podemos utilizar qualquer nome tanto para constantes quanto para as funções, no entanto, é sempre prudente lembrar que o nome deve ser o mais coerente possível. Afinal, a ideia é trabalhar em conjunto. Quanto mais legível for o seu código, mais fácil será para que seus colegas ou até mesmo você no futuro entendam o que está acontecendo.

Função para Criar uma Tarefa

Vamos criar uma função chamada “botaoAdicionar”. Dentro desta função, criaremos uma nova tarefa com um ID baseado no timestamp atual, o texto inserido e o estado inicial definido como falso. A lista de tarefas será então atualizada com a inclusão dessa nova tarefa.

const alterarToggle = (id: number): void => {
  setTarefas((prevTarefas) =>
    prevTarefas.map((tarefa) =>
      tarefa.id === id ? { ...tarefa, feito: !tarefa.feito } : tarefa
    )
  );
};

Renderização do Componente

Agora iremos renderizar todas as lógicas que fizemos em nossa aplicação.

<div className="main-container">
  <h1>Lista de Tarefas</h1>
  <ul>
    {tarefas.map((tarefa) => (
      // ...
    ))}
  </ul>
  <input
    type="text"
    placeholder="Adicionar Item"
    onChange={(e) => setInput(e.currentTarget.value)}
  />
  <button onClick={botaoAdicionar}>Adicionar</button>
</div>

O código acima refere-se à parte da renderização do componente de nossa aplicação. Abaixo, vamos dividi-lo um pouco para que isso fique mais visual para vocês.

Conteúdo do Componente:

Utilizamos o elemento <div></div> como contêiner principal (main-container) para que possamos posteriormente referenciá-lo no CSS e estilizar um pouco mais o nosso projeto.

Depois disso criamos um <h1> responsável pelo título de nossa aplicação.

Dentro dessa div, adicionaremos uma lista não ordenada <ul></ul>, um <input /> para receber a ação do usuário e um botão <button></button> para adicionar novas tarefas na lista.

Segmentando essas três partes da aplicação:

Ul: Dentro de nossa lista, temos um map que irá percorrer todo o nosso array tarefas. Veja que dentro desse map, temos um li que representa um elemento da lista e dentro dele encontramos algumas propriedades.

Vale ressaltar que o style=”” tem uma condicional para caso a tarefa já tenha sido feita. Se sim, iremos apresentá-la como concluída. Além disso, ela também tem um onClick={} responsável por alterar entre tarefa feita ou não.

Button: o botão sempre precisará de um onClick={} que receberá a função responsável por realizar a ação esperada.

Input: Como esse é o campo de preenchimento do usuário, nós precisamos adicionar um type="" que dirá a nossa aplicação o que o usuário pode escrever dentro do campo, é interessante sempre adicionar um placeholder="" isso adiciona uma mensagem no campo a ser preenchido quando ele estiver vazio e por fim adicionamos também o onChange={} que recebe a função e atualiza o valor recebido pelo input.

O nosso onChange recebe uma callback para realizar essa atualização o (e) simboliza o evento recebido inicialmente, já e.currentTarget.value é a propriedade que contém o valor atual do campo de entrada de texto no momento do evento de mudança.

Conclusão

Parabéns por concluir este tutorial! Agora você possui as habilidades fundamentais para criar sua própria lista de tarefas usando React.

Este é apenas o primeiro passo em sua jornada de desenvolvimento. Continue explorando, experimentando e aprimorando suas habilidades. Lembre-se, a prática constante é a chave para se tornar um desenvolvedor proficientes em React. Espero que este tutorial tenha sido útil e inspirador.

Boa sorte em seus futuros projetos e até a próxima semana.