본문 바로가기

[React] Todo-App을 만들어보자 (1)

Min_dev 발행일 : 2023-03-28
반응형

한가지 기술을 사용하더라도 그 기술이 어떤식으로 동작하는지 알고 조금 더 깊이있는 지식을 습득하는 것이 이번 프로젝트의 목표이다.

 

리액트를 Todo-App 만들기 목표

1. jsx문법 연습하기

2. 리액트 상태관리 기술 연습하기 (여러가지 리액트 Hook 사용해보기)

3. tailwind 사용해보기

4. 컴포넌트의 구조를 어떻게 잡아야 추 후 리팩토링이나 유지보수가 편할지 생각하면서 구현해보기

 

구현계획

1. Todo CRUD 구현하기

2. 다크모드 구현하기

3. 반응형으로 구현하기

4. localStroage에 저장하여 새로고침하거나 창을 새로 열어도 데이터 유지하기 (백엔드 연동 전까지)

5. 가능하다면 외부API와 연동시켜보기

6. 프론트 기능을 완성하면 백엔드와 연동시키기 

 

프로젝트 구조

프로젝트 구조는 아래 사진과 같습니다.

총 5개의 컴포넌트와 DarkMode를 위한 context 파일 하나로 구조를 나누었습니다.

 

 그리고 UI에 대한 설명보다는 프로젝트 내에서 상태관리를 어떻게 진행했는지를 우선적으로 포스팅하였습니다.

 

먼저 완성된 TodoApp 캡처본 보여드리고 시작하겠습니다.

 

완성된 TodoApp

 

Todo CRUD 구현

todos의 상태는 TodoList.jsx 파일에서 useState를 통해 관리하였습니다.

todo 객체는 todo = {id : id. todo : todo, status : status} 형태로 구현하였습니다.

readTodo는 로컬스토리지에 JSON형태로 등록된 Todo 배열을 가져와서 js객체로 변환해주는 함수이다. 

이 부분은 나중에 살펴보자.

 

먼저 todos의 상태에 새로운 todo를 추가해주는 부분을 살펴보겠습니다.

 

Todo 생성

해당 코드는 TodoApp의 footer 부분으로 입력 폼에 해당되는 부분입니다.

AddTodo 컴포넌트의 내부 코드를 보겠습니다.

 

 

먼저 해당 코드는 input창에 입력되는 text의 상태를 useState로 관리합니다.

 

 

input에 입력되는 text가 변경될때마다 hamdleChange 함수가 동작하여 text의 상태가 실시간으로 변경됩니다.

text입력 후 버튼을 클릭하면 handleSubmit 함수가 동작합니다. 

 

e.preventDefault()는 form 이벤트가 발생하였을 때 페이지가 재렌더링 되지 않도록 해주는 메서드입니다.

그리고 입력창이 공백이 아니고 글자 앞뒤로 공백이 없는 경우에만 props로 전달된 onAdd 함수가 실행되도록 했습니다.

 

onAdd 함수는 TodoList 컴포넌트에서 AddTodo 컴포넌트의 props로 전달된 handleAdd 함수입니다.

해당 함수는 현재 todos의 상태를 가져와서 파라메타로 전달되는(입력폼에 작성된 새로운 todo) 새로운 todo 객체를 todos 배열에 등록해줍니다.

 

Todo 가져오기

백엔드 코드와 연결시키기 전까지는 Todo를 로컬스토리지에 저장하여 사용하는데요.

여기서는 todo를 localStroage에 언제 저장시키고 가져오는지에 대한 설명을 해보려고 합니다.

 

먼저 todo를 localStroage에 저장시키는건 리액트의 useEffect 훅을 사용하여

todo의 상태가 변경될때마다 저장이 되도록 구현하였습니다. 

 

TodoList 컴포넌트 내부에 작성된 코드입니다.

디펜던시 배열에 todos를 입력하여 todos의 상태가 변경될때마다 내부의 코드가 실행되도록 하였습니다.

localStroage에 'todos'를 key로 설정하여 todos를 JSON 타입으로 변경시켜 저장하는 코드입니다.

 

그리고 localStroage에 저장된 todos는 페이지가 새로고침되거나 브라우저를 껏다켜도 남아있기 때문에 이전에 기록해놓은 todos를 다시 가져올 수 있습니다.

 

초기에 App이 렌더링 될때 todos의 useState 값을 설정하는 과정에서 readTodo 함수를 실행시킨다고 말씀드렸는데요.

 

해당 함수를 보면 localStroage에서 저장된 todos를 가져와서 todos가 존재하면 JS 객체로 변환하여 리턴하고 존재하지 않을 경우 빈 배열을 리턴하도록 구현하였습니다.

 

이렇게해서 페이지를 새로고침하거나 브라우저에 재접속을 하여도 이전에 기록한 todos를 그대로 가져올 수 있습니다.

 

 

Todo 업데이트 (완료했는지 체크)

 

Todo list 이부분은

 

위와 같은 코드로 구현이 되어있는데요.

 

먼저 업데이트의 과정을 설명드리면

todo를 완료했다는 가정하에 checkbox에 체크 하면 handleChange 함수가 동작하고 

 

함수 내부에 선언한 status의 변수값이 checkbox가 체크되었으면 'Completed' 아니라면 'Active'값을 가지게 됩니다.

 그리고 onUpdate 함수가 실행되는데 해당 함수는 TodoList에서 Todo 컴포넌트의 props로 전달된 handleUpdate 함수입니다. onUpdate의 파라미터로 전달되는 todo 객체의 status값은 'Completed'가 되어 전달됩니다.

handleUpdate로 전달받은 todo 객체는 todos를 빙글빙글 돌면서 같은 id값이 나왔을 때 그 객체 대신 새로운 객체로 들어가게되면서 업데이트된 새로운 todos 상태로 전환됩니다.

 

필터링에 대한 설명은 다음 글에서 이어서 하겠습니다.

 

Todo 삭제

todo 삭제도 간단합니다.

삭제 버튼을 클릭하면

handleDelete 함수가 동작하고 콜백함수로 TodoList 컴포넌트에서 props로 전달된 onDelete함수가 동작합니다.

 

onDelete는 TodoList 컴포넌트에 있는 handleDelete 함수인데 파라미터로 전달하는 삭제하려는 todo의 객체의 id와 동일한 기존 객체를 filter를 통해서 제거합니다.

 

여기까지 TodoApp의 CRUD 부분에 대한 설명이었고 다음 글에서는 todo 상태에 따른 필터링과 다크모드를 적용하는 방법에 대해 설명드리겠습니다.

 

 

gitHub : https://github.com/MintaekCho/Todo-App-

 

GitHub - MintaekCho/Todo-App-

Contribute to MintaekCho/Todo-App- development by creating an account on GitHub.

github.com

 

배포링크 : https://fascinating-dango-2fc3fd.netlify.app/

 

오늘머하지😵‍💫

 

fascinating-dango-2fc3fd.netlify.app

 

 

 

반응형

댓글