DEV Community

Cover image for Meu primeiro projeto com React ts + Hooks
Beatriz Oliveira
Beatriz Oliveira

Posted on • Edited on

17 7

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 :

Top comments (2)

Collapse
 
kamillyvitoria_marinhoc profile image
Kamilly Vitoria Marinho Cutrim

Muito bom 😊👏🏼

Collapse
 
srwalkerb profile image
SrWalkerB

Nice, admito que me embolei no Passo 4, pq ainda não estou familiarizado com TypeScript kfoaisjflsakmfas, article good

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay