Criando TodoList com ReactJs
Tags: react, javascript, braziliandevs, webdev
Published: 2021-11-16 23:36:56

##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.
```javascript
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.

```javascript
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:
```javascript
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**.

```javascript
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_: 

```javascript
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: 

```javascript
 <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**.

```javascript
<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:

![TodoList Render](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xp6ihr254ocre5jz456b.png)

##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.

```javascript
<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.

```javascript
{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**

```javascript
  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
![TodoList Render](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1hk784yui4qhx6h2lig.png)

##Código Final

```javascript
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;
```