Typescript로 공부를 본격적으로 들어갔다.
Typescript는 javscript의 동적 언어의 문제점을 보완해서 정적인 언어의 모습을 흉내내기 위한 컴파일러라는게 느껴졌다.
앞으로는 모든 작업에 Typescript로 작업을 들어가게 될거 같은데 그 중 Todo-list를 새롭게 적용해봤다.
types
우선 todo에 대한 타입을 declare
declare type Todo = {
id: number;
title: string;
content: string;
isDone: boolean;
};
useTodos
props로 드릴링하게 된다면 ts에선 어떻게 사용하는게 맞을까란 고민을 하면서 작업을 해봤다.
js에선 객체만 남겨주면 됐는데 확실한 타입을 알고 넘겨줘야 할거같다는 느낌을 받았다.
export default function useTodos(
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>
) {
const addTodo = (todo: Todo) => {
setTodos((prev) => [...prev, todo]);
};
const toggleTodo = (id: number) => {
setTodos((prev) =>
prev.map((todo) => {
if (todo.id === id) return { ...todo, isDone: !todo.isDone };
return todo;
})
);
};
const deleteTodo = (id: number) => {
setTodos((prev) => prev.filter((todo) => todo.id !== id));
};
return { addTodo, toggleTodo, deleteTodo };
}
Components
TodoInput
확실히 hooks로 관리하게 되니 components에 코드가 간결해지는거같다.
import React, { ChangeEvent, FormEvent, useState } from "react";
import useTodos from "../hooks/useTodos";
interface Props {
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;
}
const TodoInput = ({ setTodos }: Props) => {
const [title, setTitle] = useState<string>("");
const [content, setContent] = useState<string>("");
const { addTodo } = useTodos(setTodos);
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.name === "title") setTitle(e.target.value);
else if (e.target.name === "content") setContent(e.target.value);
else {
console.error("존재하지 않는 상태값입니다.");
}
};
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
addTodo({
id: Date.now(),
title,
content,
isDone: false,
});
};
return (
<>
<form onSubmit={handleSubmit}>
<div>
<input
type="text"
name="title"
onChange={handleChange}
placeholder="제목을 입력해주세요"
required
/>
<input
type="text"
name="content"
onChange={handleChange}
placeholder="내용을 입력해주세요"
required
/>
<button type="submit">추가</button>
</div>
</form>
</>
);
};
export default TodoInput;
TodoList
import React from "react";
import useTodos from "../hooks/useTodos";
interface Props {
todos: Todo[];
setTodos: React.Dispatch<React.SetStateAction<Todo[]>>;
}
const TodoList = ({ todos, setTodos }: Props) => {
const { deleteTodo, toggleTodo } = useTodos(setTodos);
const doneTodos = todos.filter((todo) => todo.isDone);
const notDoneTodos = todos.filter((todo) => !todo.isDone);
return (
<>
<ul>
{notDoneTodos.map(({ id, title, content }) => (
<li key={id}>
<h2>{title}</h2>
<p>{content}</p>
<button onClick={() => deleteTodo(id)}>삭제</button>
<button onClick={() => toggleTodo(id)}>완료</button>
</li>
))}
</ul>
<hr />
<ul>
{doneTodos.map(({ id, title, content }) => (
<li key={id}>
<h2>{title}</h2>
<p>{content}</p>
<button onClick={() => deleteTodo(id)}>삭제</button>
<button onClick={() => toggleTodo(id)}>완료</button>
</li>
))}
</ul>
</>
);
};
export default TodoList;
느낀점
아직 ts에 대한 이해와 코드 정리가 잘 되지 않아서 아직 더 연습이 필요하다고 느꼈다. 훅 관리도 처음으로 해본거 같은데 팀으로 작업하게되면 확실히 코드 관리도 쉬울거 같다는 느낌을 받았다.
이번 todolist에서는 기존에 한걸 복습하고 싶어 모든 방법으로 다 해봐서 복습이 확실히 됐다. 다음 프로젝트 때는 zustand랑 query로 이용해보는게 제일 재밌을거같다느 느낌을 받았다.
tjdsksro90/ts-react-todo-list (github.com)
GitHub - tjdsksro90/ts-react-todo-list
Contribute to tjdsksro90/ts-react-todo-list development by creating an account on GitHub.
github.com
브랜치별로 작업을 해서 나중에 다시 보고 싶을 때 보면 좋을 듯하다.
Level 1: React 이용 Todolist
Level 2: RTK 이용 Todolist
Level 3 : RTK + json-server 이용 Todolist
Level 4 : RTK + redux thunk 이용 Todolist
Level 5 : RTK + react-query 이용 Todolist
'TIL' 카테고리의 다른 글
[TIL][23.12.22] [프로그래머스] 2016년 JS (0) | 2023.12.26 |
---|---|
[TIL][23.12.21] [프로그래머스] 카드 뭉치 JS (1) | 2023.12.22 |
[TIL][23.12.18] [프로그래머스] 콜라 문제 JS (1) | 2023.12.18 |
[TIL][23.12.13] Single Responsibility Principle(SRP) (0) | 2023.12.13 |
[TIL][23.12.12] 리액트 아웃소싱 프로젝트 - KPT 회고 (0) | 2023.12.12 |