import React, { useState } from 'react'
import Todos from './components/Todos'
import Todo from './utils/todo'
import InsertTodo from './components/InsertTodo'
const App = () => {
const [todos, setTodos] = useState<Todo[]>([])
const addTodoHandler = (item: string) => {
const newTodo = new Todo(item)
setTodos(prevTodo => {
return [...prevTodo, newTodo]
})
}
const removeTodoHandler = (id: string) => {
setTodos(prevTodos => {
return prevTodos.filter(todo => todo.id !== id)
})
}
return (
<div>
<InsertTodo onAddTodo={addTodoHandler} />
<Todos items={todos} onRemoveTodo={removeTodoHandler} />
</div>
)
}
export default App
class Todo {
id: string
text: string
constructor(todoText: string) {
this.id = String(new Date().getTime())
// this.id = new Date().toLocaleString()
this.text = todoText
}
}
export default Todo
import React from 'react'
import { useState } from 'react'
import style from '../style/InserTodo.module.css'
const InsertTodo: React.FC<{ onAddTodo: (item: string) => void }> = props => {
const [text, setText] = useState('')
const submitHandler = (e: React.FormEvent) => {
e.preventDefault()
if (text.trim() !== '') {
props.onAddTodo(text)
setText('')
}
}
const changeHandler = (e: React.FormEvent<HTMLInputElement>) => {
setText(e.currentTarget.value)
}
return (
<div>
<form onSubmit={submitHandler} className={style.form}>
<h3>할일 추가</h3>
<input type="text" value={text || ''} onChange={changeHandler} />
<button>추가</button>
</form>
</div>
)
}
export default InsertTodo
.form {
width: 40rem;
margin: 2rem auto;
}
.form input {
width: 50%;
font: inherit;
font-size: 1.5rem;
padding: 0.5rem;
background-color: #fff;
border: none;
outline: none;
border-bottom: 2px solid #f06292;
margin-right: 1rem;
}
.form button {
font: inherit;
background-color: #f06292;
border: none;
color: #fff;
padding: 0.5rem 1.5rem;
border-radius: 4px;
cursor: pointer;
}
import React from 'react'
import Todo from '../utils/todo'
import TodoItem from './TodoItem'
import style from '../style/Todos.module.css'
const Todos: React.FC<{
items: Todo[]
onRemoveTodo: (id: string) => void
}> = props => {
return (
<ul className={style.todos}>
{props.items.map(item => (
<TodoItem
key={item.id}
text={item.text}
id={item.id}
onRemoveTodo={props.onRemoveTodo}
/>
))}
</ul>
)
}
export default Todos
.todos {
list-style: none;
margin: 2rem auto;
padding: 0;
width: 40rem;
}
import React from 'react'
import style from '../style/TodoItem.module.css'
const TodoItem: React.FC<{
text: string
id: string
onRemoveTodo: (id: string) => void
}> = props => {
return (
<li className={style.item} onClick={() => props.onRemoveTodo(props.id)}>
{props.text}
</li>
)
}
export default TodoItem
.item {
margin: 1rem 0;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
padding: 1rem;
background-color: #ffcdd2;
}