React 독학을 어느정도 진행한 시점에서 간단한 프로젝트를 진행해야 할 필요성을 느꼈다.
이론과 간단한 예제를 작성해보는 것 만으로는 내용을 전부 익히기 어려울 것 같았고 직접 뭔가를 만들어가며 몸으로 익혀야겠다고 생각했다.
프로젝트를 진행하기로 결심했으나 가장 중요한 무엇을 만들 것인지가 빠져있었다.
평소 ToDo List를 자주 사용하기 때문에 ToDo List 웹앱을 제작해볼까 했는데 이왕 만들거면 ToDo List보다 더 많은 내용을 작성할 수 있는 메모장을 만들어보자 해서 메모 웹앱으로 결정하였다.
<App>
├── <Header>
│
├── <Center>
│ ├── <MemoList>
│ │ └── <Toolbar>
│ │ └── <Modal>
│ ├── <TextInput>
│ │ └── <Toolbar>
│ │ └── <Modal>
│ └── <MemoView>
│ └── <Toolbar>
│ └── <Modal>
└── <Footer>
툴바는 검색, 리스트, 메모 작성, 메모 수정, 삭제, 취소 버튼과 모달을 상황에 맞게 출력한다.
작성과 수정, 삭제와 취소는 각각 같은 버튼이지만 상황에 따라 버튼의 이름과 기능을 변경하도록 하였다.
리스트 / 메모 작성 / 수정 버튼
해당 기능을 수행할 페이지로 이동시키는 역할을 한다.
검색 버튼
focus 시 확장되며 입력받은 내용을 <MemoList />
컴포넌트에 전달하고 해당 컴포넌트에서 검색을 수행한다.
삭제 / 취소 버튼
삭제 버튼은 실제 삭제를 담당하지 않고 모달창을 띄우는 역할을 한다.
취소 버튼은 메모 작성, 메모 수정 페이지에서 뒤로가기 기능을 수행한다.
모달
삭제 버튼 클릭시 출력되는 삭제 확인 모달이다.
삭제와 관련된 로직을 실질적으로 처리하게 된다.
메모 목록은 메모들의 제목과 작성 시간을 출력한다.
로컬스토리지의 특성상 정렬에 기준이 없고 뒤죽박죽이기 때문에 우선 스토리지의 요소들을 전부 꺼낸 뒤 시간순으로 정렬하여 목록에 나열하는 방법을 사용했다.
각 메모는 체크박스를 갖고 있다. 이 체크박스의 value는 해당 메모의 id와 동일하며, 체크될 시 checked state의 배열에 추가된다.
이 배열은 메모의 삭제에 사용된다.
메모의 작성과 수정은 하나의 버튼으로 이루어지지만 상황에 따라 버튼의 이름과 기능을 변경하였다.
1. url에 메모의 id 미포함
2. url에 메모의 id 포함
해당 프로젝트에 사용한 input은 모두 state로 value를 직접 관리하였다.
메모 수정의 경우 기존 메모의 내용을 불러온 뒤 value의 초기값으로 할당하여 기존 내용에서 이어 작성할 수 있도록 하였다.
작성/수정 내용을 업로드할 때 입력 내용이 없다면 input 요소를 진동시켜 내용을 채우도록 유도하였다.
<Toolbar />
에서 검색어를 입력 받으면 검색어를 <MemoList />
에 전달한다.
<MemoList />
에서는 전달 받은 검색어가 있을 경우 해당 검색어와 일치하는 메모만 출력하고 검색어가 없을 경우에는 모든 메모를 출력한다.
삭제와 취소는 하나의 버튼으로 이루어지지만 상황에 따라 버튼의 이름과 기능을 변경하였다.
1. 현재 페이지가 MemoView 컴포넌트일 경우
2. 현재 페이지가 MemoList 컴포넌트일 경우
3. 현재 페이지가 TextInput 컴포넌트일 경우
삭제 확인을 받는 모달이다.
삭제 버튼을 클릭 시 출력되며 모달창의 확인 버튼을 클릭하여 메모를 삭제할 수 있다.
닫기 / 취소 / 외부 여백을 클릭하여 삭제를 취소하고 모달창을 닫을 수 있다.
iPhone 11 pro 구동 화면, 기기 이미지는 iPhone X
CRA, classnames, scss, gsap, eslint, prettier, husky, lint-staged, netlify 등을 사용하여 진행했다.
사용한 색상은 다음과 같다.
안녕하세요! 게시글 너무 잘 읽었어용 저도 개인프로젝트로 메모장 관련해서 하나 만들고있는데, 이 글의 색감이랑 디자인이 너무 마음에 들어서요. 혹시 색감 배치랑 디자인적인 외관 부분을 참고하여 저의 프로젝트에 응용해도 괜찮을까요? 참고로 상업적 용도는 전혀없구요 저만의 실력 향상을 위한 솔로 프로젝트입니다!