import React, { useState } from "react";
import "./App.css";
import Todos from "./components/todo/Todos";
import Todo from "./components/todo/todo";
import InsertTodo from "./components/todo/InsertTodo";
function App() {
// 할 일
// 타입스크립트에서 빈 배열을 만들면 never타입이 됨
// never 타입은 무조건 빈 배열, 바뀌지 x
// 따라서 배열에 타입을 명시해줘야 함
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) {
// 현재 날짜, 시간으로 id 설정
this.id = new Date().toLocaleString();
this.text = todoText;
}
}
export default Todo;
import React, { useState } from "react";
import { setTextRange } from "typescript";
// onAddTodo는 함수타입이라고 명시해야 함
// <{onAddTodo : 매개변수 : 타입 ) => 반환값타입}>
const InsertTodo: React.FC<{ onAddTodo: (item: string) => void }> = (props) => {
// 타입스크립트에서는 e에 타입 명시해줘야 함
// 이벤트 객체는 React.FormEvent로 타입 사용하면 됨
const submitHandler = (e: React.FormEvent) => {
e.preventDefault();
if (text.trim() !== "") {
props.onAddTodo(text);
setText(" ");
}
};
const [text, setText] = useState("");
// input에서 일어나는 이벤트틑
// React.FormEvent<HTMLInputElement> 라고 명시해야함
const changeHandler = (e: React.FormEvent<HTMLInputElement>) => {
// target 말고 currentTarget 사용함
setText(e.currentTarget.value);
};
return (
<div>
<form onSubmit={submitHandler}>
<h3>할일 추가</h3>
<input type="text" onChange={changeHandler} value={text} />
<button>추가</button>
</form>
</div>
);
};
export default InsertTodo;
import React from "react";
import Todo from "./todo";
import TodoItem from "./TodoItem";
// Todos는 컴포넌트 타입 => React.FC (리액트의 함수형 컴포넌트)
// props의 타입 명시 (제네릭 타입 사용) => 객체 <{ items: string[] }>
const Todos: React.FC<{
items: Todo[];
onRemoveTodo: (id: string) => void;
}> = (props) => {
return (
<div>
<ul>
{props.items.map((item) => (
<TodoItem
key={item.id}
text={item.text}
id={item.id}
onRemoveTodo={props.onRemoveTodo}
/>
))}
</ul>
</div>
);
};
export default Todos;
import React from "react";
const TodoItem: React.FC<{
text: string;
id: string;
onRemoveTodo: (id: string) => void;
}> = (props) => {
return <li onClick={() => props.onRemoveTodo(props.id)}>{props.text}</li>;
};
export default TodoItem;
React.FC
, React.FormEvent<HTMLInputElement>
로 컴포넌트와 이벤트에도 타입을 명시해야 하는 부분이 새로운 개념이라 적응하기 어려웠다.새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 9주차 블로그 포스팅