✅ Context + TypeScript 기반 ToDoList 실행 흐름 정리
🟢 1. App.tsx 실행 (React 앱 진입점)
function App() {
return <TodoApp />;
}
- 앱이 시작되면 최상위 컴포넌트인
App이 실행됨
- 내부에서
TodoApp 컴포넌트를 호출함
🔵 2. index.tsx 에서 TodoApp 정의
const TodoApp = () => {
return (
<TodoProvider>
<h1>📝 To Do List</h1>
<TodoInput />
<TodoList />
</TodoProvider>
);
};
- 전역 상태 관리를 위해
TodoProvider로 전체를 감쌈
- 내부에
TodoInput, TodoList 컴포넌트가 배치됨
🟡 3. TodoContext.tsx 실행 (상태 + Context 정의)
const TodoContext = createContext<TodoContextType | null>(null);
createContext를 통해 Context 생성
- 기본값은
null, 타입은 TodoContextType
export const useTodoContext = () => {
const ctx = useContext(TodoContext);
if (!ctx) throw new Error("useTodoContext must be used within TodoProvider");
return ctx;
};
- 전역 상태를 가져오는 커스텀 훅 정의
TodoProvider 내부에서만 사용 가능하도록 보호
export const TodoProvider = ({ children }: { children: React.ReactNode }) => {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodo = (text: string) => {
const newTodo: Todo = {
id: Date.now(),
text,
completed: false,
};
setTodos((prev) => [...prev, newTodo]);
};
const toggleTodo = (id: number) => {
setTodos((prev) =>
prev.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
return (
<TodoContext.Provider value={{ todos, addTodo, toggleTodo }}>
{children}
</TodoContext.Provider>
);
};
const [text, setText] = useState("");
<form onSubmit={handleSubmit}>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="할 일을 입력하세요"
/>
<button type="submit">추가</button>
</form>
🟣 5. TodoList.tsx 실행 (할 일 목록 보여주기)
const { todos } = useTodoContext();
<ul>
{todos.map((todo) => (
<TodoItem key={todo.id} todo={todo} />
))}
</ul>
🟤 6. TodoItem.tsx 실행 (할 일 항목 UI)
interface Props {
todo: Todo;
}
export const TodoItem = ({ todo }: Props) => {
const { toggleTodo } = useTodoContext();
return (
<li
onClick={() => toggleTodo(todo.id)}
style={{
textDecoration: todo.completed ? "line-through" : "none",
cursor: "pointer",
}}
>
{todo.text}
</li>
);
};
✅ 여기까지가 초기 렌더링
🟢 7. 사용자 입력 후 "추가" 클릭 시
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (text.trim()) {
addTodo(text);
setText("");
}
};
🔵 8. addTodo() → 상태 변경
setTodos((prev) => [...prev, newTodo]);
🟠 9. 상태 변경 감지 → 리렌더링
TodoList가 자동 리렌더링됨
.map()으로 최신 할 일 목록 다시 그림
🔴 10. 최종 결과
- 새 할 일 표시됨
- 클릭 시 완료 상태 토글 가능
🎯 전체 흐름 요약
App → TodoApp → TodoProvider
├ TodoInput → text 상태 관리
└ TodoList → todos 목록 출력
사용자 입력 → addTodo(text) → setTodos()
→ 상태 변경 → TodoList 자동 리렌더링 → UI 갱신됨
최종 완성본 확인

😺 코드확인
github: ToDoList