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
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
Também adicione o pacote de ícones:
# usando npm
npm install @material-ui/icons
# usando yarn
yarn add @material-ui/icons
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.
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';
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
}
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)])
}
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>
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>
)
}
o link do projeto :
Top comments (2)
Muito bom 😊👏🏼
Nice, admito que me embolei no Passo 4, pq ainda não estou familiarizado com TypeScript kfoaisjflsakmfas, article good