Summary
- 주제 : 날짜별로 할 일을 기록하고 그 목록을 관리할 수 있는 투두 애플리케이션 개발
- 개발기간 : 2022-02 ~ 2021-02 (약 2주)
- 참여인원 : 1명
- 프로젝트 목표 : 리액트 네이티브로 투두 애플리케이션을 개발하면서 Redux Toolkit 라이브러리와 custom hook 기반 page-usePage 패턴 개발 방식을 익힌다.
- 깃허브 링크 : https://github.com/aroundthistime/Todo_App
Stack
- Typescript
- React Native
- React Query
- Emotion
- Redux Toolkit
Content
날짜별로 할 일을 기록하고 점검할 수 있는 투두 애플리케이션이다. 처음 애플리케이션을 실행하면 오픈 API를 통해 가져온 명언을 확인할 수 있으며 해당 팝업은 원하는 경우 24시간 노출되지 않도록 설정할 수 있다. 투두는 제목, 내용, 기한, 우선순위를 설정할 수 있다. 또한 캘린더를 활용하면 각 날짜별로 할 일의 목록과 완수율을 확인할 수 있다. 어플리케이션의 배경화면은 기본적으로 7종류가 제공되며 그 외에도 사용자의 기기에 탑재된 이미지 파일을 적용할 수도 있다. (물론 추가한 사용자의 파일을 다시 삭제하는 것 역시 가능하다.)
Features
- 명언 팝업 (React Query, Redux toolkit)
- 투두 목록에서 각 투두 완료/복원(미완료)/삭제 (react-native-swipe-list-view)
- 투두 추가 및 수정 (redux-persist)
- 날짜별로 투두 목록 및 완수율 확인
- 배경화면 설정 (react-native-fs, react-native-image-picker)
Images
Takeaway
- Custom Hook을 활용한 디자인 패턴
기존의 리액트 프로젝트들을 진행하면서 컴포넌트의 라인 수 자체가 너무 길어지다 보니 가독성이 떨어지는 경우를 종종 확인했습니다. 그래서 이번 프로젝트에서는 Container-Presenter 패턴을 버리고 Custom Hook을 활용한 디자인 패턴을 도입했습니다. 그를 통해 컴포넌트 내부 로직에 해당하는 영역과 뷰적인 부분에 해당하는 영역을 분리하여 코드에 대한 가독성을 향상시킬 수 있었습니다.
- Redux Toolkit을 활용한 상태관리
이번 프로젝트에서는 Redux Toolkit 라이브러리를 활용하여 투두 목록, 배경화면, 명언 노출 여부 등의 전역상태들을 관리했습니다. 그를 통해 초기기존의 Redux 방식을 활용할 때의 복잡한 구조와 다르게 하나의 slice 안에서 초기 상태, 리듀서, 액션타입, 액션 생성함수들을 관리할 수 있었습니다. 그리고 이러한 상태값들을 redux-persist를 활용하여 asyncstorage에 저장하였습니다. 본 프로젝트에서는 관리되는 모든 전역 상태가 그 값의 특성상 어플리케이션의 종료 후에도 유지되는 것이 필요했기 때문에 해당 방법을 통해 별도로 asyncstorage에 접근하는 작업 없이 상태를 처리할 수 있었습니다. 또한 createSelector 메소드를 활용하여 컴포넌트에서 실제로 state값들을 참조할 때 최소한의 리렌더링이 이루어질 수 있도록 프로그램을 작성함으로써 성능을 개선할 수 있었습니다.
- 성능 개선을 위한 노력
리액트 네이티브가 네이티브 어플리케이션에 비해 성능적인 이슈를 가지고 있는 것은 이미 알려진 사실입니다. 따라서 이번 프로젝트에서는 기능의 구현과 함께 성능의 최적화를 통해 리액트 네이티브가 가진 단점을 최소화하고자 노력했습니다. 그 노력의 예시로 위에서 언급한 custom Selector를 활용하였으며 Flatlist 등에서 익명 함수의 사용을 지양했습니다. (기존의 코드 스타일에서는 renderItem 등의 함수에서 Arrow Function으로 선언한 익명함수를 활용하였는데 이는 매번 새롭게 함수가 정의되기 때문에 성능 저하의 원인이 될 수 있기 때문입니다.) React의 memo와 useCallback을 통해 컴포넌트, 값 혹은 함수의 불필요한 재생성을 방지했습니다. 특히 Props의 변화가 크게 없거나 자식의 컴포넌트들이 props를 전달받지 않는 순수 컴포넌트라면 memoization의 효율성이 극대화되기 때문에 무조건적으로 React.memo()를 활용했습니다. (물론 무분별한 memoization은 리렌더링 비용보다 memoization의 비용이 더 높을 수 있기 때문에 조심하였습니다.)
- 로컬 파일 액세스하기
배경화면과 관련하여 로컬 저장소에 접근하는 기능이 필요했습니다. 따라서 우선적으로 react-native-image-picker를 활용하여 기기에 포함된 이미지 파일을 불러온 후 react-native-fs를 활용하여 해당 이미지 파일을 DocumentDirectory에 복사하도록 하였습니다. 이렇게 복사된 파일들은 react-native-fs의 readDir함수를 통하여 가져온 후 asset에 포함된 기본 제공 이미지들과 함께 선택지로 제공됩니다. 사용자가 임의로 추가한 이미지 파일을 삭제하고 싶은 경우에는 동일 라이브러리의 unlink함수를 통해 도큐먼트 폴더에서 해당 이미지를 삭제했습니다.
- Emotion을 활용한 스타일 관리
본 프로젝트에서는 평소에 애용하던 styled-components가 아닌 Emotion을 활용하였습니다. 물론 둘의 사용하는 데 큰 차이가 존재하지는 않았지만 css 방식의 스타일링 문장을 그대로 사용할 수 있다는 점에서 코드의 통일성이 확보된다는 점이 가독성의 측면에서 장점으로 작용할 수 있겠다는 생각이 들었습니다. 또한 메모리적인 측면에서도 Emotion이 장점을 보이기 때문에 앞으로 개인 프로젝트에서는 Emotion을 주로 활용할 것 같습니다.
'프로젝트 (잡다한)' 카테고리의 다른 글
패스트푸드 키오스크 (0) | 2022.02.22 |
---|---|
게임 전적조회 사이트 (리그오브레전드) (1) | 2022.02.22 |