📝 React 투두리스트 만들기
📌 시작하며
간단히 일정하기 위해 만들어볼 것.
할 일 추가, 생성, 완료 + 삭제 기능 구현 CRUD 구현
구현하면서 알게 된 내용을 기록하는 것이다.
📌 투 두 리스트 목표
- 🖊️ 메모 생성, 삭제, 수정 기능 (CRUD)
- ✅ localStorage 연동
- ✅ 상태관리 개선: Zustand 적용
- npm install zustand
아래 목록은 추가 기능으로 하고 싶은 목록이다.
- 🔒 로그인 연동: Firebase Auth
- ☁️ DB 저장: Supabase/Firebase Firestore
- 드래그 & 드롭으로 리스트 이동
- 날짜별 할 일 (캘린더 적용 가능할까? )
📌 패키지 사용
- zustand - 스토어 사용 (새로 고침시 목록 유지)
사실 이거 아니여도 로컬스토리지를 사용해도 괜찮다. - React Icons - 다양한 아이콘 이용
아래와 같이 에러가 나오는데
TS2786: 'MdCheckBoxOutlineBlank' cannot be used as a JSX component.
Its return type 'ReactNode' is not a valid JSX element.
Type 'undefined' is not assignable to type 'Element | null'.
이 에러 나올 경우 React 18/19에서 발생하는 타입 호환성 이슈 때문에 나타나는 대표적인 문제라고 한다.
왜 발생하는가?
- react-icons에서 MdCheckBoxOutlineBlank의 타입이 ReactNode로 되어 있고,
- React 18/19(특히 TypeScript 5+ 및 @types/react 18.3+ 이상)에서는 JSX 요소로 쓸 때 ReactNode 대신 React.ElementType 또는 FunctionComponent여야만 <MdCheckBoxOutlineBlank />처럼 사용 가능한데 타입이 좀 더 엄격해지면서 저런 에러가 뜬다고 한다.
📌 해결 방법
react-icons 업그레이드
이 방법이 가장 권장되면서 간단한 방법이다.
최신 버전(2024년 8월 기준 v5.2.0 이상)에서는 이 문제가 대부분 해결되었다.
npm install react-icons@latest
# 또는
yarn add react-icons@latest
설치 후, 프로젝트를 재시작하면 된다.
📌 투 두 리스트 기본 구성 (컴포넌트)
- TodoTemplete - 투두 전체영역
- TodoList - 리스트 전체
- TodoItem - 할 일 한 개
- TodoInsert - 할 일 입력
App아래 TodoTemple이라고 감싸고 TodoInsert, TodoList가 존재한다.
TodoInsert
TodoInsert는 할 일을 입력하는 팝업형태로 구성되었다.
아래 투두리스트 갈무리를 보면 우선 11개는 만들어 놓았다.
위에서 언급한 TodoInsert는 할 일 입력도 하지만, 수정, 그리고 삭제까지 포함되어있다.
오른쪽 하단에 + 버튼을 누르면 할 일 추가하는 팝업이 뜨지만 이미 할 일이 있을 때 터치(클릭) 했을 경우 수정하는 팝업으로 변경하도록 해놓았다. 더불어 삭제 기능까지🗑️
할일 추가와 수정할 때는 엔터만 입력을 하더라도 추가 및 수정이 되게 했다. 이건 따로 자바스크립트를 이용한 것이 아니라 html의 form요소 기본을 살렸다.
<form
className="todo-form"
onSubmit={
selectedTodo
? () => {
onUpdateTodo(selectedTodo.id, todoText);
}
: handleSubmit
}
>
<form>요소에 onSubmit을 넣어 button type을 submit을 한다면 굳이 다른 스크립트를 넣지 않아도 엔터기능이 자동으로 들어간다.
여기서 주의 할점이 두가지가 있는데
1. 추가적으로 버튼이 들어갈 때는 무조건 타입을 type="button"을 해줘야한다.
2. onSubmit을 할 경우 새로고침을 하는데 새로고침을 안하려면 event.preventDefault();를 넣어줘야 한다.
//할 일 등록
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!todoText.trim()) {
alert("할 일을 입력해주세요");
inputRef.current?.focus();
return;
}
onAddTodo(todoText);
setTodoText("");
onInsertToggle();
};
TodoList, TodoItem
TodoList안에 TodoItem 컴포넌트가 있는데 사용자따라 달라질 수 있겠지만 저는 TodoItem을 만들어 여기에 반복문이 들어가게 해놓았다.
TodoList는 그냥 <ul></ul>이고, TodoItem은 리스트안에 들어가는 <li></li>이다.
굳이 나눌필요는 없지만 <ul></ul> 바깥에서 혹시 추가적으로 코딩이 들어갈 수 있다는 생각에 나누어보았다.
📌 마무리하며...
기본적으로 만들어보았고, 다른 투두리스트 웹앱들을 참고하여 좀 더 기능을 추가하고 싶은 생각이 들었다.
목표는 로그인 기능을 넣고 회원마다 할 일을 저장하는 기능,
캘린더 기능을 넣어 캘린더에서 할 일을 작성하고 읽을 수 있는 기능
드래그 드롭으로 할일을 이동할 수 있는 기능
과연 이렇게를 추가적으로 개발을 완료될지는 모르지만 완료가 된다면 좋은 공부가 될거 같다.