This can be used to learn component abstraction, useReducer conversion, style abstraction, and oh so much more...
Last active
September 29, 2022 14:28
-
-
Save destinio/bfa1f250ae36558f5fc95542d735f65f to your computer and use it in GitHub Desktop.
Very Basic all in one TODO list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { BaseSyntheticEvent, useEffect, useState } from 'react' | |
interface Todo { | |
userId: number | |
id: number | |
title: string | |
completed: boolean | |
} | |
function Home() { | |
const [todos, setTodos] = useState<Todo[]>(null!) | |
const [newTodo, setNewTodo] = useState('') | |
useEffect(() => { | |
fetch(`https://jsonplaceholder.typicode.com/todos`) | |
.then(res => res.json()) | |
.then(data => setTodos(data.slice(0, 5))) | |
}, []) | |
if (!todos) return <h1 style={{ textAlign: 'center' }}>Loading...</h1> | |
function handleNewTodoChange(e: BaseSyntheticEvent) { | |
setNewTodo(e.target.value) | |
} | |
function handleAdd(e: BaseSyntheticEvent) { | |
e.preventDefault() | |
setTodos(prev => [ | |
{ | |
userId: 1, | |
id: Date.now(), | |
title: newTodo, | |
completed: false, | |
}, | |
...prev, | |
]) | |
setNewTodo('') | |
e.target.focus() | |
} | |
function handleDeleteTodo(id: number) { | |
setTodos(prev => prev.filter(t => t.id !== id)) | |
} | |
function handleMarkAsComplete(id: number) { | |
setTodos(prev => | |
prev.map(t => { | |
if (t.id === id) { | |
return { | |
...t, | |
completed: !t.completed, | |
} | |
} | |
return t | |
}) | |
) | |
} | |
return ( | |
<div style={{ maxWidth: 600, margin: 'auto', padding: '1rem' }}> | |
<form onSubmit={handleAdd}> | |
<input | |
style={{ padding: '1rem', fontSize: '2rem', marginBottom: '2rem' }} | |
type="text" | |
value={newTodo} | |
onChange={handleNewTodoChange} | |
/> | |
<button | |
disabled={newTodo.length === 0 && true} | |
type="submit" | |
style={{ padding: '1rem', fontSize: '2rem', marginBottom: '2rem' }} | |
> | |
add | |
</button> | |
</form> | |
{todos.length === 0 && <h1>Please add a todo</h1>} | |
{todos.map((t, i) => ( | |
<div | |
key={i} | |
style={{ | |
display: 'flex', | |
alignItems: 'center', | |
gap: '1rem', | |
}} | |
> | |
<div | |
onClick={() => handleDeleteTodo(t.id)} | |
style={{ fontSize: '2rem', color: 'red' }} | |
> | |
✖ | |
</div> | |
<div | |
onClick={() => handleMarkAsComplete(t.id)} | |
style={{ fontSize: '2rem', color: 'green' }} | |
> | |
✔ | |
</div> | |
<h2 | |
style={{ | |
textDecoration: t.completed ? 'line-through' : 'none', | |
color: t.completed ? 'lightgray' : 'inherit', | |
}} | |
> | |
{t.title} | |
</h2> | |
</div> | |
))} | |
</div> | |
) | |
} | |
export default Home |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment