
Como construir uma lista de tarefas com React? | Tutorial
Todo desenvolvedor quando começa a estudar React, acaba se deparando com dois projetos simples para fazer prova de conceito, o contador de cliques e a lista de tarefas. Nessa publicação construíremos uma lista de tarefas, indo desde a instalação de um projeto React default até salvar as tarefas no localStorage no navegador.
E de bônus, vocês ganham um contador de cliques que é criado por default pela ferramenta de inicialização do React que usaremos .
Requisitos:
Acessando o terminal
Para iniciar o projeto React, vamos precisar acessar o terminal para rodar alguns scripts.
- No linux: pressione CTRL + ALT + T;
- No Windows: pressione WINDOWS + R, digite CMD e pressione enter;
- No Mac: pressione COMMAND + spacebar, digite terminal e pressione enter.
Se você tiver usando o VSCode, pode usar o terminal interno dele.
Iniciando um projeto React com Vite
Com o terminal aberto, você pode digitar "ls" para listar as pastas e arquivos dentro da sua pasta atual, "cd [nome-da-pasta]" para entrar em uma pasta, "cd .." para voltar para a pasta acima.
Com esses comandos, navegue até a pasta que você deseja instalar o projeto e então digite "npm create vite@latest". Com isso o Vite vai fazer algumas perguntas, pressione "y" para continuar.

Escolha um nome para o seu projeto

Nesse ponto, o Vite vai perguntar qual framework você deseja utilizar
Escolha React

E finalmente, Typescript + SWC

Com isso o Vite vai criar um projeto React padrão com Typescript na sua pasta, você pode rodar os seguintes comandos para:
- entrar na pasta do projeto "cd [nome-do-projeto]";
- instalar as dependências para o Vite "npm install";
- iniciar o projeto num ambiente de desenvolvimento "npm run dev".

Depois de iniciar o projeto com o último comando, você verá o seguinte no terminal e então podemos abrir o navegador e acessar
http://localhost:5173 (trocando o número da porta, pelo número mostrado no seu terminal) para ver o projeto default do Vite.
O Vite vai manter o projeto rodando e fazendo auto reload do servidor toda vez que algum arquivo do projeto for salvo, com isso o navegador vai exibir sempre a versão mais atual do seu código.

Depois de rodar todos esses comandos no terminal, é hora de abrir o VSCode na pasta do seu projeto, para começar a desenvolver.
Limpando o projeto default
A estrutura de pastas que você verá será a seguinte. vamos deletar a pasta assets e os arquivos App.css e Index.css.

Depois de deletar os arquivos, vamos abrir o main.tsx e remover a importação do index.css na linha 4, o código deverá ficar assim:

Com o main.tsx atualizado, podemos fechá-lo e partir para o App.tsx, remover o import do useState na linha 1, remover o import do reactLogo na linha 2, remover o import do App.css na linha 3, remover [count, setCount] na linha 6 e finalmente deletas as linhas de 9 a 29.
*as referências às linhas são todas antes de qualquer deleção.
O código deverá ficar como segue:

Criando um estilo global (globalStyle)
No React, trabalhamos com a criação de estilos para cada componente, mas falaremos disso em breve. Primeiro vamos criar um globalStyle, que vai definir os estilos comuns a toda a aplicação.
Dentro da sua pasta src, crie um arquivo globalStyle.css e adicione as propriedades como na imagem a seguir.
Note:
- Você pode brincar com os códigos hexadecimais das cores, para criar uma paleta de cores diferente para sua lista de tarefas;
- A última propriedade .App faz referência a propriedade className do App.tsx. (tente mudar o nome em ambos os arquivos, para ver que vai continuar funcionando).

Podemos agora voltar para o nosso App.tsx e importar o globalStyle, como segue.

Criando componentes
Agora estamos prontos para começar a criar nossos componentes, vamos criar uma pasta chamada components (e aqui o nome é só uma convenção, mas você pode dar o nome que preferir para a pasta, só lembre-se de alterar também nos imports) dentro da pasta src e dentro da pasta components, três outras pastas:
- InputForm - será o campo de entrada para novas tarefas;
- TaskCard - será o card da tarefa, mostrando o que ela é e um botão para remover;
- TodoList - será um componente para unir os outros dois e listar cada tarefa.
Também vamos criar uma pasta types, dentro da src.

InputForm
Dentro da pasta InputForm, vamos criar um index.tsx e um style.css.
A primeira coisa a fazer no index.tsx é importar o style.css e exportar uma função de nome InputForm. Essa função deverá receber uma outra função de nome saveTask como parâmetro e retornará um form. Nas linhas 3 e 5, estamos declarando a tipagem do nosso componente, usando uma interface.

Depois de criar a estrutura dos componentes, vamos adicionar funcionalidade a ele.
Importe o FormEvent e o useState do react, e então defina um estado para a tarefa, esse estado será atualizado toda vez que digitarmos na tela.
O useState funciona como uma variável, com o conceito de imutabilidade e precisa ser recriado toda vez que for atualizado. O fato de ele ser recriado toda vez faz com que o React renderize o componente novamente, porque um novo estado foi criado.
Vamos falar em mais detalhes sobre como o React gerencia a renderização dos componentes em outro post.
useState returna dois valores, o primeiro (task nesse caso) é a variável imutável que irá armazenar o estado e o segundo (setTask) é a função que deve ser chamada para recriar o estado.
Com o estado pronto, vamos criar uma função para gerenciar a ação de salvar a tarefa, essa função irá:
- Receber o event do formulário;
- Prevenir o comportamento padrão de submissão do formulário;
- Chamar a função saveTask recebida pelo componente como uma propriedade (veremos o que essa função faz nas seções a seguir);
- Definir o estado como vazio, limpando os campos de digitação na tela

Por fim, iremos:
- Dizer para o formulário executar a nossa função de gerenciamento, quando for submetido;
- Adicionar o input que irá mostrar o valor do estado e permitirá que o usuário digite a sua tarefa. Sempre que algo for digitado, o estado é atualizado com o novo valor;
- Adicionar um botão para submter o formulário.

Com o InputForm.tsx finalizado. Vamos para o style.css e adicionar propriedades CSS para cada elemento do componente inputForm.
Olhe o seu navegador antes e depois de adicionar as propriedades ao arquivo style.css para ver como o CSS deixa o projeto mais bonito.

TaskType
Dentro da pasta types, crie um arquivo Task.ts e exporte uma interface com o nome Task, que será a tipagem da nossa tarefa. Essa interface deverá ter um id e uma message.
(dica: se você aceitar o desafio no final do post, você terá que adicionar uma nova propriedade aqui nesse tipo)

TaskCard
Dentro da pasta TaskCard, crie um index.tsx e um style.css.
No index.tsx, vamos começar importando o tipo Task que acabamos de criar e o style.css.
A seguir, declare a interface com as propriedades do componente e exporte uma função de nome TaskCard que deve receber as propriedades declaradas na interface. Esse componente irá retornar uma div.

Pra continuar, vamos precisar instalar uma biblioteca de ícones, execute npm install phosphor-react no seu terminal, dentro da pasta do projeto.
Depois de instalar a biblioteca, vamos importar o TrashSimple dela.
Adicione,
- uma tag p passando a mensagem da tarefa.
- um botão que chamará a função que deleta a tarefa ao ser clicado, esse botão irá exibir o ícone que acabamos importar

Finalmente, vamos adicionar CSS ao style.css do nosso componente.

TodoList
Dentro da pasta TodoList, crie um index.tsx e um style.css.
No index.tsx importe o style.css e exporte uma função com o nome TodoList, essa função deve retornar uma section.

Para continuar, vamos instalar uma biblioteca para criação de uuid (universal unique id), execute npm install uuid no terminal, dentro da pasta do projeto.
Depois da instalação, vamos importar o uuid, o tipo Task e os outros dois componentes que desenvolvemos previamente, InputForm e TaskCard.
Com as importações prontas, vamos:
- Criar um estado para armazenar todas as tarefas;
- Criar uma função saveTask, que irá receber a mensagem da tarefa e adicionar a tarefa no estado;
- Criar uma função para gerenciar a deleção de uma tarefa, essa função irá receber o id da tarefa e removê-la do estado.

Depois de declarar as funções, vamos completar o retorno do componente, adicionando
- Um h2 com o título do app;
- Nosso componente InputForm passando a função saveTask como uma propriedade;
- Uma div com uma lista do componente TaskCard. Para cada uma das tarefas, vamos renderizar um TaskCard passando a tarefa e a função de deleção como propriedades. Toda vez que adicionamos uma lista de elementos no returno de um componente React, precisamos passar uma propriedade key, para que o React saiba a ordenação dos elementos na hora de renderizar o componente de novo.

Finamlente, para salvar a nossa lista de tarefas no localStorage do navegador e não perder as informações ao dar reload na página, vamos usar outro hook do React, o useEffect.
Esse hook realiza efeitos colaterais no nosso componente. Ele é usado para engatilhar alguma ação sempre que o componente renderizar pela primeira vez ou algum estado ou função for recriada.
No primeiro useEffect que vamos usar, chamaremos a função de leitura da API do localStorage, se houver alguma informação salva, iremos adicionar essa informação ao estado tasks. Esse hook receberá um array de dependências vazio, indicando que ele só precisa executar no momento em que o componente for renderizado.
O segundo useEffect irá salvar as tarefas do estado tasks no localStorage sempre que esse estado for alterado. Como podemos ver no array de dependências, passamos o estado tasks.


Para deixar tudo mais bonito, vamos adicionar CSS ao nosso style.css.

App
Com o componente TodoList pronto, vamos chamá-lo no nosso App.
Abra o App.tsx e dentro da tag main, passe o componente de TodoList, para ser renderizado.
E com isso você deverá ser capaz de acessar o navegador e adicionar e remover tarefas da sua lista de tarefas.

O que fazer a seguir?
Agora que você concluiu sua lista de tarefas, você pode evoluí-la adicionando novas funcionalidades, aqui vão alguns desafios:
- Troque as fontes e cores nos seus aquivos de style.css para deixar sua lista com uma personalização que seja sua cara.
- Adicione uma data de criação as tarefas e mostre essa data em cada tarefa. Você pode verificar a API de data do navegador para ver como pegar a data atual. Adicione uma propriedade data na sua tarefa, que agora só tem message e id.
Se você seguiu o tutorial até aqui e implementou o projeto, me mande fotos dele no LinkedIn, vou adorar ver o projeto de vocês.
Conclusão
Listas de tarefas são projetos simples que todo desenvolvedor implementa quando começa a estudar React. Existem infinitas formas de fazer uma lista de tarefa e eu quis trazer uma que seja simples de implementar e ao mesmo tempo trouxesse alguns conceitos do React (como os hooks) e do navegador (como a API de localStorage).
Me contem nos comentários o que vocês acharam do projeto e deixem suas sugestões para próximos posts.
Que tal:
- Um tutorial de como instalar e configurar o VSCode?
- Uma explicação de diferentes formas de iniciar um projeto React?
- Um conceito mais avançado: Como o React lida com o fluxo de renderização?