Skip to content

jakkku/note-in-travel-client

Repository files navigation

유튜브 영상
<Stand-up 발표 영상>

여행 줍줍 🧳

여행일정을 세우고 공유할 수 있는 모바일 앱입니다.
지도 상의 공유된 일정을 확인할 수 있으며, 일정을 수행할 수 있습니다.
여행 중 현재 위치에 쪽지를 남길 수 있고, 주변에 쪽지가 있다면 내용을 읽어 볼 수 있습니다.


💡프로젝트 동기

여행을 가는 것을 좋아하지만, 여행 일정을 세우는 것은 어려운 저와 같은 사람을 위한 어플을 만들고 싶었습니다.
여행일정을 손쉽게 만들고 공유할 수 있으며, 다른사람의 여행일정에 참여할 수 있습니다.
어린시절 쪽지를 숨겨놓고 찾던, 보물찾기를 기억하시나요? 여행 중 추억과 이야기를 쪽지로 남길 수 있습니다. 쪽지는 근처에 있어야만 확인할 수 있습니다.


🛠기술 스택

Front

  • React Native
  • React Navigation
  • Redux(redux toolkit)

Back

  • Node.js
  • MongoDB
  • Express

Testing

  • Jest
  • react-test-renderer
  • @testing-library/react-native


💁‍♂️프로젝트 설명

메인페이지

  1. 공유되어 있는 일정을 지도에서 확인 할 수 있습니다.
  2. 거리가 가까운 일정들은 묶어서 확인이 가능합니다.
  3. 공유되어 있는 일정을 지도에서 확인 할 수 있습니다.
  4. 거리가 가까운 일정들은 묶어서 확인이 가능합니다.

일정 생성

  1. 검색을 통하여 목적지를 선택 및 추가할 수 있습니다.
  2. 특정 장소를 즐겨찾기에 추가할 수 있습니다.
  3. 즐겨찾기한 장소를 간편하게 일정에 추가할 수 있습니다.
  4. 방문할 장소의 순서를 변경할 수 있습니다.
  5. 여행 일정의 제목을 입력하고 저장할 수 있습니다.

마이페이지

  1. 내가 생성한 일정과 즐겨찾기한 일정의 목록을 확인할 수 있습니다.
  2. 일정을 눌러 상세일정을 확인할 수 있습니다.

일정 상세 페이지

  1. 일정의 점수 및 상세 정보를 확인 할 수 있습니다.
  2. 타인의 일정일 경우, 즐겨찾기를 추가할 수 있습니다.
  3. 하단의 일정수행버튼은 길게 누르면 일정수행 모드로 전환되고, 현재 나의 위치를 지도상에 표시해줍니다.
  4. 일정 수행모드에서는 현재 나의 위치에 쪽지를 남길 수 있고, 근처의 쪽지를 확인할 수 있습니다.
메인 페이지 일정 생성(장소 검색) 일정 생성(즐겨찾기 장소) 일정 생성(순서 변경)
메인페이지 일정생성_장소검색 일정생성_즐겨찾기_장소 일정생성_순서변경
일정 생성(저장) 마이페이지 일정 수행 & 쪽지
일정생성_저장 마이페이지 일정수행 및 쪽지 작성


🚀키워드

Redux Normalize, Re-rendering
코드 링크
지난 1차 프로젝트에서 AWS 요금이 청구된 경험을 하며 '서버에 요청을 보내는 부분도 최적화가 필요하지 않을까?'라는 생각을 하게되었습니다. 원인은 리팩토링 과정에서 소켓 연결 로직에서의 실수로 발생한 일이었지만, 이번 프로젝트에서 서버 요청에서의 최적화를 해보고 싶었습니다.
로그인 시 유저관련 정보에 생성한 일정, 즐겨찾기 목록 등의 데이터를 함께 받는 것은 자연스럽다고 판단하였고, 즐겨찾기 목록 등의 데이터를 위한 요청을 별도로 분리하고 싶지 않았습니다. 하지만 한번의 로그인 요청을 통하여 받게되는 데이터를 redux store에 하나의 state로 관리하는 것은 비효율적이라고 생각하였고, 서버에서 유저 정보를 관리하는 데이터 형태와는 다른 형태로 redux state를 normalize하여 관리하게 되었습니다. 추가적인 이점으로 특정 상태의 업데이트가 불필요하게 다른 컴포넌트의 리렌더링을 유발하는 경우를 줄일 수 있었습니다.

Custom Hook, Abstraction
코드 링크
hook도 결국은 함수라는 생각으로 함수 추출의 기준에 따라 작성하려고 하였고, 그 과정에서 하나의 hook이 어느정도의 기능을 포함하는 것이 적절한가에 대한 결정이 쉽지 않다는 것을 느꼈습니다.
이번 프로젝트에서 저는 다음과 같은 기준으로 custom hook을 만들고자 하였습니다.

  • 관심사의 분리
  • 로직의 재사용성

로직의 재사용성을 우선적으로 고려하여 hook을 분리하였더니, 하나의 컴포넌트에서 여러개의 custom hook의 반환값을 다뤄야하는 경우가 발생하였습니다. 관심사의 분리를 위하여, 여러 custom hook을 포함하는 또 다른 하나의 custom hook을 작성하는 것도 하나의 방법이었습니다. 하지만 1차 프로젝트에서 계층이 깊어질수록 코드의 흐름을 파악하는데 어려움을 겪었던 것과 유지보수에서의 어려움을 겪었던 경험이 있었고, 다른 방법을 선택하였습니다.
여러 custom hook의 반환값을 인자로 전달받아 로직을 수행하는 custom hook을 작성하는 방식을 선택하였습니다. 덕분에 로직의 계층구조가 깊어지지않아서 흐름을 파악하기 수월하고 코드의 재사용성에서의 장점이 있었습니다. 하지만 반대로, 컴포넌트 내에 작은 단위의 로직들이 순차적으로 동작한다는 점에서 관심사의 분리가 조금 아쉽지 않았나하는 생각도 할 수 있었습니다.
DRY한 코드를 작성하기 위하여 함수의 추출이라는 선택을 할 수 있습니다. 하지만 재사용성, 관심사의 분리 등의 장점이 있는가 하면 반대로 커플링, 계층이 깊어지는 경우 코드 흐름파악의 어려움, 그로인한 유지보수의 어려움 등 단점도 분명히 존재합니다. 우리가 어떠한 방식으로 적용하느냐에따라 단점이 장점보다 커질수도, 장점이 단점보다 커질수도 있습니다. 코드를 작성할때 선택이 필요한 순간들이 존재하는데, 더 좋은 결과를 위해서는 늘 trade off에 대해 고민해야하고 결정에 대한 근거를 명확히하는 것의 중요성과 어려움을 느낄 수 있는 경험이었습니다.

Spatial Hash Grid, Clustering, Opimization
코드 링크
핵심적인 기능 중, 현재 나의 위치를 기반으로 주변에 있는 쪽지만을 보여줘야하는 기능이 있습니다.
현재 수행 중인 일정내의 모든 쪽지를 매번 검사하여, 보여줄지 숨길지의 여부를 판단할 수도 있었습니다. 하지만 쪽지의 수가 많아질 경우 나의 위치가 조금 변경될때마다 모든 쪽지를 모두 검사하여 거리를 계산하는 것은 매우 비효율적이라고 판단하였고, 효율적인 방법을 고민하였습니다.
1차 프로젝트에서 게임관련 로직을 공부할 기회가 있었고, 그때 공부한 spatial hash gird을 참고하여 문제를 해결할 수 있었습니다.
일정 내에 쪽지의 수가 많아져도 현재 내가 속한 단위 영역과 인근의 영역만을 탐색하는 방식으로 최적화를 적용할 수 있었고, spatial hash grid를 만드는 함수의 경우 memo를 이용하여 필요한 경우에만 재실행되도록 적용하였습니다. 위의 방식은 메인 페이지의 공유된 일정들을 합쳐서 보여주는, Clustering에도 활용할 수 있었습니다.
React Three Fiber를 공부하면서 알게된 지식이, 전혀 관련이 없을 거라고 생각했던 지도를 다루는 부분에 사용할 수 있었다는 부분이 재미있는 경험이었습니다.

Testing
코드 링크(utils)
코드 링크(hooks)
코드 링크(components)
Test-driven Development(이하 TDD)는 오류를 최소화할 수 있고 이후에 코드를 다시 봤을때 로직의 의도를 파악하는데 도움을 주는 등 많은 이점이 있다고 생각합니다. 하지만 React Native를 처음 사용해본다는 걱정과 짧은 시간에 개발을 해야하기에 시간이 부족하지 않을까하는 걱정에 온전히 적용하지는 못하였으나, 개발을 진행하며 꼭 필요하다고 생각한 부분에 적용하였고 대표적으로 Spatial Hash Grid로직을 작성하며 TDD의 장점을 느낄 수 있었습니다.
내부적으로 기능이 복잡하다고 생각하여 test를 먼저 작성한 후 하나씩 해결하는 방식으로 코드를 작성하였습니다. 이후 완성된 로직을 사용하며 여러 오류를 접하였으나, 테스트 코드를 통하여 검증된 부분이 있기에 버그를 찾는데 많은 시간을 절약할 수 있었고 TDD를 기반으로 작성한 코드에서는 거의 오류가 발생하지 않았습니다.
React를 사용하였는가, React Native를 사용하였느나, Redux를 사용하였는가, React Navigation을 사용하였는가 등 어떠한 기술 스택을 이용하였는가에 따라 테스트 코드의 작성 방식이 조금씩 다르기때문에 각각의 경우에따라 다른 방식을 적용해야한다는 점을 알게되어 재밌고 좋은 경험이었습니다. TDD에 대해 더 공부하여, 다음에는 더 발전한 방법으로 TDD기반 개발을 진행해보고 싶다는 생각을 하였습니다.

Version, Frame Work
react native는 react와 달리, 테스트 코드 작성을 위하여 추가적인 환경설정이 필요했습니다.
jest를 사용하기 위해 공식문서를 참고하여 설정을 잡고, 사용한 기술스택에 따른 추가적인 설정을 완료하였습니다. 하지만 테스트는 올바르게 작동하지 않았습니다.
원인은 react-test-renderer의 버전이었습니다. react와 reat-test-renderer의 최신버전은 v17.0.2이지만, expo(v4.4.4)를 사용하여 프로젝트를 생성할 경우 react v16.13.1로 생성됩니다. 그로인해, 버전의 다름으로 발생된 오류였고, react-test-renderer의 버전을 낮추는 것으로 문제를 해결하였습니다.
프레임워크를 사용할 경우, 내부적으로 어떤 라이브러리를 사용하고 버전은 어떤 버전을 사용하는지 등을 꼼꼼히 확인하는 것이 얼마나 중요한지를 느낄 수 있는 경험이었습니다.


🏃프로젝트 기간

프로젝트는 총 3주간 진행하였습니다.

1주차 2주차 3주차
21.05.03 ~ 21.05.07 21.05.08 ~ 21.05.16 21.05.17 ~ 21.05.21
기획 개발 마무리
브레인 스토밍
목업
스키마 설계
개발 일정 계획
기능 개발
리팩토링
리팩토링
테스트 코드 작성
배포


🙇‍♂️아쉬운 점

  1. 개발 단계에서 android와 ios의 호환성 고려
    개발 초기 단계에서부터 emulator를 이용하여 android와 ios 모두를 고려하면 좋지 않았을까하는 아쉬움이 있습니다. ios배포를 생각해서 계획을 하였으나, 개발이 거의 완료된 시점에서 ios뿐 아니라 android의 배포도 진행해야겠다는 결정을 했습니다. 하지만 ios기기로 진행상황을 확인하며 개발을 했기때문에, android로도 추가로 확인이 필요했습니다. 같은 button 컴포넌트여도 ios와 android에서 보여지는 모습이 다를 뿐아니라, 세부 기능마다 특정 os마다 지원여부가 다른 경우도 존재했습니다.
    ios와 android에서 같은 codebase를 공유할 수 있다는 react native의 장점을 잘 활용하지 못했다는 아쉬움이 있었고, 비록 초기에 ios배포를 생각했다고하여도 호환성을 고려하여 개발을 하는 것이 이후 계획의 변경에대해 더욱 유동적으로 대응할 수 있겠다는 생각을 했습니다.

  2. react native의 특징을 이용한 최적화
    react native에서 stack이 남아있어서 unmount가 되지않는 특징이 처음에는 어색하고 불편했습니다.
    react에서 컴포넌트의 mount, unmount라는 lifecycle을 당연하게 생각하고 받아들이고 있었기 때문에, stack이 unmount되지 않는 특징으로 인해 나타나는 현상들을 이상하다고 생각하여 react의 특징과 비슷하게 동작하도록 flag를 이용하여 unmount, mount시키는 방식을 적용하였습니다.
    하지만 stack이 unmount되지않는 특징을 잘 사용한다면, mount, unmount로 소모되는 불필요한 리소스를 줄일 수 있다고 생각합니다. 단순히 다른 특징이라고 이상하다고 생각하여 기존과 비슷한 방식으로 적용하기보다, react native만의 특징을 받아들이고 이를 잘 활용했다면 최적화 측면에서 이점을 얻을 수 있지 않았을까하는 아쉬움이 남았습니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published