Meu primeiro projeto com React ts + Hooks

beatrizoliveira

Beatriz Oliveira

Posted on March 2, 2021

Meu primeiro projeto com React ts + Hooks

Bom, o projeto que será apresentado é bem simples, mas serviu para consolidar conhecimentos básicos sobre React, optei por utilizar o typescript, pois o código se torna mais legível e simples, mas se preferir pode utilizar javascript normal.

No projeto será utilizado:

  • Typescript
  • React Hooks
  • Material UI

1) Passo:

Criar o projeto com create-react-app TodoList usando ou não o template de Typescript.

npx create-react-app TodoList --template typescript

# or

yarn create react-app TodoList --template typescript
Enter fullscreen mode Exit fullscreen mode

2) Passo:

Já com o projeto criado instale o Material ui.

# utilizando o npm
npm install @material-ui/core

# utilizando o yarn
yarn add @material-ui/core
Enter fullscreen mode Exit fullscreen mode

Também adicione o pacote de ícones:

# usando npm
npm install @material-ui/icons

# usando yarn
yarn add @material-ui/icons
Enter fullscreen mode Exit fullscreen mode

3) Passo:

Crie um o arquivo TodoList.tsx onde ficará todo o código do projeto, crie também uma pasta styles contendo TodoList.css se você quiser estilizar o projeto.
Alt Text

4) Passo:

Em TodoList.tsx importe o hook useState, TextField, ButtonIcons, AddIcon e DeleteIcon do material ui.

import React, { useState } from 'react';
import { TextField, IconButton } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import DeleteIcon from '@material-ui/icons/Delete';
Enter fullscreen mode Exit fullscreen mode

Em seguida vamos criar uma interface , interface no typescript é a forma de nomear os tipos, com isso criaremos nossa interface TodoItem passando o valor do id como number e value como uma string.

interface TodoItem {
    id: number
    value: string
}
Enter fullscreen mode Exit fullscreen mode

Crie um state useState set e setList com um array do tipo TodoItem , no seu valor default vamos passar um array com id: 0, e o uma string vazia value: ''. Depois iremos criar funções do tipo handleChange, handleAdd e handleDelete para lidar com esse list :


export const TodoList: React.FC = () => {
    const [list, setList] = useState<TodoItem[]>([{ id: 0, value: '' }])

    const handleChange = (value: string, id: TodoItem['id']) => {
        setList(prev => prev.map(item => item.id === id ? { ...item, value } : item ))
    }

    const handleDelete = (id: TodoItem['id']) => {
        setList(prev => prev.filter(item => item.id !== id))
    }

    const handleAdd = (index: number) => {
        const newItem = { id: count ++, value: '' }
        setList(prev => [...prev.slice(0, index + 1), newItem, ...prev.slice(index + 1)])
    }

Enter fullscreen mode Exit fullscreen mode

5) Passo:

No return passe uma list.map pegando o item e o index, renderizando uma div,onde iremos passar uma key com valor item.id que será único para cada item, em seguida vamos renderizar também o TextField do material ui com um value e o onChange. Depois passamos o IconButton também do material ui rederizando o IconAdd com um onClick e faremos a mesma coisa com o IconDelete, porém passando o handleDelete ao invés do handleAdd.


return (
        <div>
          {list.map((item, index) => (
            <div key={item.id}>
              <TextField
                value={item.value}
                onChange={e => handleChange(e.currentTarget.value, item.id)}
              />
              <IconButton onClick={() => handleAdd(index)}>
                <AddIcon />
              </IconButton>

              {list.length > 1 && (
                <IconButton onClick={() => handleDelete(item.id)}>
                  <DeleteIcon />
                </IconButton>
              )}
            </div>
          ))}
        </div>

Enter fullscreen mode Exit fullscreen mode

Obs.1: a list.length é a quantidade da lista, ou seja, ela sempre vai começar com 1 item.
Obs.2: Também criaremos uma váriavel let count = 1 para simular um id.

Resultado

O TodoList.tsx ficará assim:

import React, { useState } from 'react';
import { TextField, IconButton } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import DeleteIcon from '@material-ui/icons/Delete';

interface TodoItem {
    id: number
    value: string
}

let count = 1

export const TodoList: React.FC = () => {
    const [list, setList] = useState<TodoItem[]>([{ id: 0, value: '' }])

    const handleChange = (value: string, id: TodoItem['id']) => {
        setList(prev => prev.map(item => item.id === id ? { ...item, value } : item ))
    }

    const handleDelete = (id: TodoItem['id']) => {
        setList(prev => prev.filter(item => item.id !== id))
    }

    const handleAdd = (index: number) => {
        const newItem = { id: count ++, value: '' }
        setList(prev => [...prev.slice(0, index + 1), newItem, ...prev.slice(index + 1)])
    }

    return (
        <div>
          {list.map((item, index) => (
            <div key={item.id}>
              <TextField
                value={item.value}
                onChange={e => handleChange(e.currentTarget.value, item.id)}
              />
              <IconButton onClick={() => handleAdd(index)}>
                <AddIcon />
              </IconButton>

              {list.length > 1 && (
                <IconButton onClick={() => handleDelete(item.id)}>
                  <DeleteIcon />
                </IconButton>
              )}
            </div>
          ))}
        </div>
      )
    }
Enter fullscreen mode Exit fullscreen mode

o link do projeto :

💖 💪 🙅 🚩
beatrizoliveira
Beatriz Oliveira

Posted on March 2, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related