- 타입 스크립트 기초 - (2)2025년 03월 07일
- redpome
- 작성자
- 2025.03.07.:43
https://redpome.tistory.com/39
타입스크립트 기초 -( 1 )
Vite을 통해 React+Typescript 조합으로 타입스크립트 기초를 배우자 타입 명시import Name from "./components/Name.tsx";const App = () => { return ( );};export default App; 처음 만들 때 생성되는 App 컴포넌트에서 위와
redpome.tistory.com
이전 내용에 이어서 작성한다, CRUD에서 Delete와 Update를 다룬다.
const handleDeleteTodo = async (id: Todo["id"]) => { fetch(`http://localhost:5000/todos/${id}`, { method: "DELETE", }); setTodoList((prev) => prev.filter((todo) => todo.id !== id)); };
먼저 id로 할 일을 구분하면서 삭제하는 핸들러를 위와 같이 정의하였다.
인자에 특정 타입을 정해주기 위해 Todo["id"]라는 타입을 지정한 것이다.
... <TodoList todoList={todoList} onDeleteClick={handleDeleteTodo} /> ... type TodoListProps = { ... onDeleteClick: (id: Todo["id"]) => void; }; ... function TodoList({ todoList, onDeleteClick }: TodoListProps) { ... {todoList.map((todo) => ( <TodoItem key={todo.id} {...todo} onDeleteClick={onDeleteClick} /> ... type TodoItemProps = Todo & { onDeleteClick: (id: Todo["id"]) => void }; function TodoItem({ id, title, completed, onDeleteClick }: TodoItemProps) { return ( ... <button onClick={() => onDeleteClick}>삭제</button> ...
삭제 버튼에 onClick이벤트에 onDeleteClick을 넘겨줘야하므로 TodoItem 컴포넌트에 onDeleteClick 인자를 넣었다.
이때 TodoItemProps에서 Todo["id"]에 해당하는 인자의 타입을 받고 onDeleteClick 콜백에서 아무것도 반환하지 않으므로 void를 반환하도록 명시했다.
TodoList는 중간에 있는 컴포넌트이니까 일단 위와 같이 쓰고 넘어간다.
최상위 부모 컴포넌트에서는 이젠 핸들러를 onDeleteClick에 직접 넘겨주고있다.
Update
completed의 값을 변경할 수 있는 로직은 다음과 같다.
type ToggleTodo = Omit<Todo, "title">;
먼저 위와 같은 타입을 지정했다. id와 title을 제외한 completed 타입을 제외하고 써야하므로 핸들러에서 다음과 같이 작성한다.
const handleToggleTodo = async ({ id, completed }: ToggleTodo) => { await fetch(`http://localhost:5000/todos/${id}`, { method: "PATCH", body: JSON.stringify({ completed: !completed }), }); setTodoList((prev) => prev.map((todo) => { if (todo.id === id) { return { ...todo, // 완료 상태를 반전 completd: !completed, }; } return todo; }), ); };
인자로 넘겨주는 id, completed의 타입을 지정할 때 Omit을 이용하여 필요한 인자의 타입만을 명시했다.
이후에는 삭제 함수와 마찬가지로 컴포넌트에 Props로 전달해준다.
import "./App.css"; import { type Todo, getTodos } from "./components/todos"; import { useState, useEffect } from "react"; type ToggleTodo = Omit<Todo, "title">; function App() { const [todoList, setTodoList] = useState<Todo[]>([]); useEffect(() => { getTodos().then((data) => setTodoList(data)); }, []); const [title, setTitle] = useState(""); const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => { setTitle(e.target.value); }; const handleAddTodo = async () => { const newTodo: Todo = { id: crypto.randomUUID(), title, completed: false, }; await fetch("http://localhost:5000/todos", { method: "POST", body: JSON.stringify(newTodo), }); setTodoList((prev) => [...prev, newTodo]); setTitle(""); }; const handleDeleteTodo = async (id: Todo["id"]) => { fetch(`http://localhost:5000/todos/${id}`, { method: "DELETE", }); setTodoList((prev) => prev.filter((todo) => todo.id !== id)); }; const handleToggleTodo = async ({ id, completed }: ToggleTodo) => { await fetch(`http://localhost:5000/todos/${id}`, { method: "PATCH", body: JSON.stringify({ completed: !completed }), }); setTodoList((prev) => prev.map((todo) => { if (todo.id === id) { return { ...todo, completed: !completed, }; } return todo; }), ); }; return ( <> <TodoList todoList={todoList} onDeleteClick={handleDeleteTodo} onToggleClick={handleToggleTodo} /> <input type="text" value={title} onChange={handleTitleChange} /> <button onClick={handleAddTodo}>입력</button> </> ); } type TodoListProps = { todoList: Todo[]; onDeleteClick: (id: Todo["id"]) => void; onToggleClick: (toggleTodo: ToggleTodo) => void; }; function TodoList({ todoList, onDeleteClick, onToggleClick }: TodoListProps) { return ( <> {todoList.map((todo) => ( <TodoItem key={todo.id} {...todo} onDeleteClick={onDeleteClick} onToggleClick={onToggleClick} /> ))} </> ); } type TodoItemProps = Todo & { onDeleteClick: (id: Todo["id"]) => void; onToggleClick: (toggleTodo: ToggleTodo) => void; }; function TodoItem({ id, title, completed, onDeleteClick, onToggleClick, }: TodoItemProps) { return ( <div> <br></br> <div>id:{id}</div> <div onClick={() => onToggleClick({ id, completed })}>title:{title}</div> <div>completed:{completed}</div> <button onClick={() => onDeleteClick(id)}>삭제</button> <br></br> </div> ); } export default App;
'타입스크립트' 카테고리의 다른 글
타입스크립트 기초 -( 1 ) (0) 2025.03.06 다음글이전글이전 글이 없습니다.댓글