TS를 익히기 위해 만들어본 TODO 앱입니다
이번 글에서는 State와 Props로만 구성되어 있던 앱을
context를 이용하도록 수정하는 것을 목표로 합니다
TodoContext.tsx 파일을 생성했습니다
Todo의 타입을 새로 생성한 파일 안으로 옮기고,
context에 사용할 타입과 Context를 생성했습니다
// TodoContext.tsx
import { createContext, SetStateAction } from "react";
export interface ITodo {
idx: number;
title: string;
project: string;
}
interface ITodoContext {
todos: ITodo[];
editIdx: number | null;
setTodos: React.Dispatch<SetStateAction<ITodo[]>>;
setEditIdx: React.Dispatch<SetStateAction<number | null>>;
}
export const TodoContext = createContext({} as ITodoContext);
todos는 context로 전달되는 setTodos를 이용해 제어될 것입니다
addTodo, updateTodo, deleteTodo 함수를 삭제하고, Provider로 child를 감싸주었습니다
// TodoList.tsx
//...
import { ITodo, TodoContext } from "../contexts/TodoContext";
const TodoList = () => {
const [todos, setTodos] = useState<ITodo[]>([]);
const [editIdx, setEditIdx] = useState<number | null>(null);
const Items = () => {
return todos.map((item) => {
if (item.idx === editIdx) {
return (
<EditTodo
idx={item.idx}
title={item.title}
project={item.project}
></EditTodo>
);
} else {
return (
<Todo idx={item.idx} title={item.title} project={item.project}></Todo>
);
}
});
};
return (
<div className="todo-list-container">
<TodoContext.Provider value={{ todos, editIdx, setTodos, setEditIdx }}>
{Items()}
<CreateTodo />
</TodoContext.Provider>
</div>
);
};
수정 버튼 클릭, 삭제 버튼 클릭 시 동작을 변경합니다
// Todo.tsx
// ...
import { useContext } from "react";
import { TodoContext, ITodo } from "../contexts/TodoContext";
const Todo = (props: ITodo) => {
const { todos, setTodos, setEditIdx } = useContext(TodoContext);
const handleClickDeleteBtn = () => {
const newTodo = todos.filter((item) => {
return item.idx !== props.idx;
});
setTodos(newTodo);
};
const handleClickUpdateBtn = () => {
setEditIdx(props.idx);
};
//...
};
추가 버튼 클릭 동작을 변경합니다
// CreateTodo.tsx
import { useContext, useState } from "react";
import { TodoContext } from "../contexts/TodoContext";
const CreateTodo = () => {
const { todos, setTodos } = useContext(TodoContext);
//...
const handleClickCreateBtn = () => {
let todo = { idx: idx, title: title, project: project };
setTodos([...todos, todo]);
setIdx(idx + 1);
setEmpty();
};
//...
};
// EditTodo.tsx
import React, { useContext, useEffect, useState } from "react";
import { TodoContext, ITodo as EditTodoProp } from "../contexts/TodoContext";
const EditTodo = (props: EditTodoProp) => {
const { todos, setTodos, setEditIdx } = useContext(TodoContext);
//...
const handleClickSubmitBtn = () => {
const newTodo = todos.map((item) => {
if (item.idx === props.idx) {
return { idx: props.idx, title, project };
} else {
return item;
}
});
setTodos(newTodo);
setEditIdx(null);
};
//...
};
전체 소스 : Github