오늘은 To-do-list를 만들어봤다.
투두리스트는 기본기(CRUD)에 정말 좋은 예제라고 생각한다.
어떤 기능인지 살펴보면 ,
인풋창에 데이터를 입력하고 버튼을 누르면 밑에 목록이 생기고 ,
체크를 하면 밑줄이 처진다.
X를 누르면 해당 컴포넌트가 삭제된 것처럼 보이는 기능이다.
(현재 서버 없이 혼자 만드는 것이기 때문에 API에 요청을 보내진 않는다.)
전체적으로 보겠다.
투두 리스트를 담은 배열 안에,
정보들이 담긴 객체가 한덩이 한덩이 있어야 한다.
객체 안엔 {id,text , checked}의 앖이 들어가야 한다.
그러니까 최종으로 보면 이런 느낌이다.
[
{id : 유니크한 값, text : 내가 쓴 내용, isCompleted : true & false} ,
{id : 유니크한 값, text : 내가 쓴 내용, isCompleted : true & false} ,
{id : 유니크한 값, text : 내가 쓴 내용, isCompleted : true & false}.
]
변수는 id,text ,checked 가 필요하다.
다만, checked는 생성할 때 false로 생성해야 한다.
필요한 함수는 3개다.
1. Add 버튼에 들어가는 submit함수
2. check기능에 toggle 함수
3. 삭제기능을 하는 delete 함수.
하나하나 살펴보겠다.
1. Add 버튼에 들어가는 submit함수
const Todo = () => {
const [todos, setTodos] = useState<TTodo[]>([]);
const [text, setText] = useState("");
const onSubmitHandler = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setTodos((prevTodos) => [
...prevTodos,
{
id: Date.now(), // id값이 유니크하게 현재 시간으로 생성한다.
text, //text : text를 이런 식으로 줄일 수 있다!
checked: false, // true , 했는지 안했는지 체크
},
]);
setText("");
};
//HTML
<form className="grid gap-4" onSubmit={onSubmitHandler}>
<div className="flex gap-2">
<Input
type="text"
placeholder="Enter Todo List"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<Button
type="submit"
className="bg-[#4f4f4f] text-white w-[77px] shrink-0 rounded-lg"
>
Add
</Button>
</div>
</form>
HTML을 보면 form안에 , submit타입 버튼으로 전송시키고
form엔 onSubmit={서브밋함수} 를 넣어준다.
전송하기 전에 , 이벤트 입력칸을 초기화한다.
setTodos(기존 투두배열이 매개변수 )로 들어올 때
[ ...기존투두들 + {지금 생성하는 투두}]
이런 느낌이다.
[기존투두들]을 스프레드 연산자로 괄호를 벗겨버리고
지금 생성하는 투두와 합친다.
text입력한 state도 초기화시켜준다.
2.check기능에 toggle 함수
체크박스를 눌렀을 때에 필요한 함수다.
//
const toggleTodo = (id: number) => {
setTodos((todos) =>
todos.map((todo) =>
todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo
)
);
};
return (
//체크박스
<CheckBox checked={todo.isCompleted}
onToggle={() => toggleTodo(todo.id)} >
<span
className={twMerge(
"text-[#35383E]",
todo.isCompleted && "line-through"
)} >
{todo.text}
</span>
</CheckBox>
)
이 함수가 진짜 중요한데 ,
1. Todo리스트 중에서 , map을 한바퀴 돌린다.
2.[투두,투두,투두] 이렇게 있으면 , 투두를 첫번째부터 끝까지 id값을 본다.
3.내가 선택한 id와 검사하는 id가 같으면 => isCompleted의 값을 반전시킨다.
html을 보겠다.
checked 라는 값이 todo안에 isCompleted에 의존한다는 뜻이다.
onToggle은 onClick과 다르게 내장되어 있는 값이 아닌 , 임의로 만들어낸 값이다.
(CheckBox 까보면 onChange={onToggle}임.)
그냥 이름 이쁘게 한거임.
3.Delete 함수
delete버튼을 눌렀을 때 기능하는 함수다.
const deleteTodo = (id: number) => {
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
<Button
className="border border-[#4f4f4f] rounded w-[23px] h-[23px] flex justify-center items-center"
onClick={() => deleteTodo(todo.id)}
>
삭제버튼을 클릭하면
내가 누른 todo의 id , 투두 모여있는 배열의 id가 같지 않는 것만 필터링한다.
=> 내가 누른 것만 삭제되는 것이다.
서버와 주고 받았을 때부터 느끼지만 , 기본적이지만 생각을 좀 해야 풀 수 있는 내용이라 생각한다.