Criando TodoList com ReactJs

Introdução

Nesse tutorial iremos desenvolver um "TodoList" em ReactJs da maneira mais simples possível, sendo assim, não iremos focar em estilização do mesmo. Recomendo que tenha noção básica de JavaScript.

Criando o projeto

Para iniciarmos o projeto, abra seu terminal e use o seguinte comando

npx create-react-app todolist

Após a criação, dirija-se até o diretório e abra seu VisualStudio Code

Limpando arquivos desnecessários

Para esse tutorial, poderemos remover alguns arquivos desnecessários de nossa aplicação.

Na pasta src, remova os arquivos:

App.test.js
index.css
logo.svg
reportWebVitals.js
setupTests.js

Você também deverá retirar a importação desses arquivos no App.js.

Parte 01

Logo de início deveremos fazer a importação do useState no App.js, pois estamos desenvolvendo um TodoList, ou seja, teremos alterações de estado (adição, remoção) de itens na lista de afazeres.

import { useState } from 'react';

Assim, estaremos aptos a utilizar o Hook.

Agora, deveremos criar o estado inicial da lista, para isso, utilizamos o useState, sendo um hook que retorna um array com dois valores, o primeiro é o estado atual e imutável, já o segundo uma função que irá alterar o estado do componente quando a mesma for ativada.

const [ todo, setTodo ] = useState([]);

-Todo representa o primeiro valor, logo o estado atual.
-setTodo representa o segundo valor, logo a função que irá realizar as alterações. (Por padrão costumamos nomear o segundo valor com "set" e logo após o nome dado ao primeiro valor).

O valor entre parenteses do useState representa o valor INICIAL do estado, como estamos criando uma lista de afazeres, o valor inicial é um Array que poderá conter vários itens.

Agora iremos criar outro estado para os novos itens a serem adicionados nesse array:

const [newTodo, setNewTodo] = useState('');

Dessa vez o estado inicial é uma string vazia, pois é o valor inicial do input do tipo texto que iremos inserir na nossa aplicação.

Parte 02

Com nossos estados criados, iremos desenvolver o que será renderizado, para isso adicionaremos um input.

function App() {
  const [todo, setTodo] = useState([]);
  const [newTodo, setNewTodo] = useState('');

  return (
    <>
      <h1>Todo List</h1>
      <input
        type="text"
        value={newTodo}
        onChange={(item) => setNewTodo(item.target.value)}
      />
    </>
  );
}

Para envolvermos várias tags HTML, podemos utilizar uma div ou então fragments <></> e todo o conteudo dentro do mesmo.

Criamos um input do tipo texto; no valor passamos o newTodo, sendo identico ao do estado já criado e onChange passamos uma função, onde conforme o estado é alterado, ele atualiza seu valor (value={newTodo}).

Ou seja, o valor (texto) atual presente no input criado, será adicionado ao nosso estado, com isso poderemos futuramente fazer com que esse valor seja renderizado na lista de afazeres.

Para que possamos adicionar esse valor em uma lista, iremos adicionar um botão que ao ser clicado, chamará a função addNewTodo:

function addNewTodo() {
    setTodo([...todo, newTodo]);
    setNewTodo('');
  }

Na primeira linha, chamamos a função do nosso primeiro estado, onde seu valor inicial é um array vazio e definimos agora que seu valor será tudo que estava presente nesse array antes (para isso utilizamos o spread), e no segundo parâmetro passamos o newTodo, ou seja, toda alteração que for feita nesse estado, após ser clicado no botão de "Adicionar", essa alteração/valor será adicionado ao nosso estado inicial da aplicação (todo).

Já na segunda linha, definimos que ao adicionar o novo valor no nosso estado, não podemos deixar o valor/texto do nosso input com o que foi digitado, devemos retirar tudo e transformar nosso estado inicial em uma string vazia novamente.

O botão a ser criado:

<button onClick={() => addNewTodo()}>Adicionar</button>

Recapitulando: Ao ser clicado, chamará nossa função addNewTodo(), que irá adicionar o novo valor ao nosso estado atual e logo após resetar o valor escrito no input.

Parte 03

Agora iremos renderizar todos esses valores em uma lista, para isso utilizaremos o map.

<ul>
    {todo.map((item) => (
       <li>
         {item}
       </li>
    ))}
</ul>

Ou seja, a cada item/todo/valor novo adicionado ao nosso array de todos, o map irá percorrer essa lista de array e renderizar um por um em forma de lista. No código acima, passamos como parâmetro item, sendo assim, cada item presente no todo, será renderizado um a um, até que o ultimo seja renderizado.

Escrevemos o código entre chaves pra mostrar que se trata de um código javascript e não HTML.

Com isso, chegamos a uma tela semelhante a essa:

Parte 04

Assim como podemos adicionar itens/afazeres ao nosso array, podemos também excluir o mesmo.

Sendo assim, iremos criar dentro do map um botão para que seja renderizado a cada item.

<button onClick={() => removeTodo(index)}>Deletar</button>

Como podemos ver, ao ser clicado ele chama a função removeTodo que tem como parâmetro index. Esse parâmetro nós podemos identificar ele no próprio map, é o segundo valor a ser passado na função.

{todo.map((item, index) => (
   <li>
     {item}
   <button onClick={() => removeTodo(index)}>Deletar</button>
   </li>
 ))}

Deveremos passar esse parâmetro também na função, para que possamos identificar o item. Ele funciona como identificador único, ID

function removeTodo(index) {
    let tmpArray = [...todo];
    tmpArray.splice(index, 1);
    setTodo(tmpArray);
  }

Criamos uma variável tmpArray, que define um array temporário, onde utilizamos o spread para adicionar tudo que contemos em nossa lista.

Utilizamos o splice e passamos como parâmetro o index (identificador único que utilizamos como parâmetro na função e que passamos ele no map) e definimos que ele irá retirar apenas um item a partir do index 1.

O método splice() altera o conteúdo de uma lista, adicionando novos elementos enquanto remove elementos antigos.

E para finalizar, definimos o novo valor do estado (setTodo), com o valor do nosso array temporário tmpArray, onde já foram feitas as modificações de exclusão de item.

Resultado da renderização

Código Final

import { useState } from 'react';

function App() {
  const [todo, setTodo] = useState([]);
  const [newTodo, setNewTodo] = useState('');

  function addNewTodo() {
    setTodo([...todo, newTodo]);
    setNewTodo('');
  }

  function removeTodo(index) {
    let tmpArray = [...todo];
    tmpArray.splice(index, 1);
    setTodo(tmpArray);
  }

  return (
    <>
      <h1>Todo List</h1>
      <input
        type="text"
        value={newTodo}
        onChange={(item) => setNewTodo(item.target.value)}
      />
      <button onClick={() => addNewTodo()}>Adicionar</button>
      <ul>
        {todo.map((item, index) => (
          <li>
            {item}
            <button onClick={() => removeTodo(index)}>Deletar</button>
          </li>
        ))}
      </ul>
    </>
  );
}

export default App;

19