본문으로 건너뛰기
Back to Projects
팀 프로젝트 (FE 2 / BE 2 / Design 1)

Fly:On

패러글라이딩 비행·관광 일정을 만들고 카드 순서를 편집하는 모바일 앱입니다.

내 역할일정 카드 편집·인증 상태 복원 구현, EAS 배포·원스토어 출시

렌더링 개선같은 로컬 드래그 동작의 React Profiler total commit duration 211.5ms → 72.9ms (약 66% 감소)

원스토어 앱 보기 ↗

2025.06 - 2025.11 · Frontend / Mobile

TypeScriptReact NativeExpoTanStack Query
사용자
비행·관광 일정을 계획하는 모바일 사용자
해결 과제
비행·관광지를 고른 뒤 일정을 만들고 순서를 바꾸는 작업을 모바일에서 이어서 할 수 있어야 했습니다.
내 기여
팀의 모바일 프론트엔드에서 일정 카드 이동·순서 편집, 작성 상태 관리, 앱 시작 시 인증 상태 복원을 구현했습니다. EAS 배포와 원스토어 출시를 진행했습니다.
기술 선택 이유
작성 중인 선택값은 Zustand로, 서버에서 조회한 일정·장소 데이터는 TanStack Query로 분리해 편집 상태와 조회 결과가 섞이지 않게 했습니다.
결과
비행·관광지를 선택해 일정을 만들고 카드 순서를 편집한 뒤 저장된 일정을 확인할 수 있는 앱을 원스토어에 출시했습니다.
Product screens

실제 사용 화면

일정 카드를 길게 눌러 이동하고 비행·관광 일정의 순서를 바꾸는 화면
User flow

서비스 이용 흐름

  1. 01

    비행·관광지 선택

  2. 02

    일정 생성

  3. 03

    카드 이동·순서 편집

  4. 04

    저장된 일정 확인

Case studies

문제 해결

01

드래그할 때 손가락보다 늦게 따라오는 일정 카드

문제
  • 사용자는 여러 비행·관광 일정을 손가락으로 끌어 원하는 순서에 놓아야 했습니다. React Native에는 이 흐름을 그대로 제공하는 Drag & Drop API가 없어 제스처, 카드 위치 계산, 목록 순서 변경을 직접 연결해야 했습니다.
  • 이 과정에서 드래그 좌표가 바뀔 때마다 목록 전체가 다시 렌더링되면 카드가 손가락 움직임을 늦게 따라왔습니다.
해결
  • PanResponder로 손가락 이동을 추적하고 각 카드의 layout을 측정해 어느 위치로 옮길지 계산했습니다. 이동 중인 카드는 floating layer에서 따로 그려 목록 전체가 제스처 좌표를 따라 갱신되지 않게 했습니다.
  • React DevTools Profiler로 같은 동작을 전후 비교한 뒤 React.memo와 Zustand selector를 적용했습니다.
확인

같은 로컬 동작을 전후 비교한 결과, React DevTools Profiler의 total commit duration은 211.5ms → 72.9ms, 평균 commit duration은 17.6ms → 6.6ms로 줄었습니다.

02

작성 중인 일정과 서버에서 받은 일정의 충돌

문제
  • 사용자가 아직 저장하지 않은 선택값과 서버에 이미 저장된 일정 데이터를 같은 상태로 관리하면, 단계 이동이나 재조회 때 작성 중인 값이 덮일 수 있었습니다.
해결
  • 일정 생성 단계와 사용자의 선택값은 Zustand의 useScheduleStore가 관리하고, 일정·관광지·숙소처럼 서버가 원본인 데이터는 TanStack Query가 관리하도록 나눴습니다.
  • 다음 단계로 이동할 수 있는 조건은 validateNextStepEnabled 순수 함수로 분리하고 Jest 테스트를 작성해 화면과 무관하게 검증했습니다.
03

선택 지역 밖의 장소까지 불필요하게 조회

문제
  • 사용자가 제주 지역을 골랐는데도 지도가 전국 범위로 열리거나 이동할 때마다 장소를 다시 요청하면, 원하는 장소를 찾기 어렵고 네트워크 요청도 늘어났습니다.
해결
  • 지도 이동 범위를 선택 지역의 boundary로 제한했습니다. marker 조회에는 TanStack Query의 enabled와 staleTime을 적용해 좌표가 준비된 뒤 요청하고, 짧은 시간 안에는 같은 데이터를 다시 가져오지 않게 했습니다.
04

앱을 다시 열 때 로그인 화면이 잠시 보이는 현상

문제
  • 앱을 시작하자마자 로그인 여부를 판단하면 보안 저장소에서 token을 읽기 전까지 기존 사용자도 비로그인 상태로 처리됐습니다. 이때 로그인 화면이 잠시 나타나거나 인증이 필요한 API가 먼저 실행될 수 있었습니다.
해결
  • 앱 시작 시 SecureStore에서 token을 복원하는 준비 상태를 두었습니다. 복원이 끝난 뒤에만 인증이 필요한 화면과 Query를 활성화해 화면 깜빡임과 불필요한 요청을 막았습니다.
기술 설계 더 보기처리 흐름 · 기술 선택 · 대안
01

기술 선택과 이유

  • React Native + Expo: 모바일 제스처, 지도, 라우팅을 같은 런타임에서 구성했습니다.
  • PanResponder: 제스처 이벤트와 위치 계산을 직접 제어하기 위해 사용했습니다.
  • Zustand: 일정 생성 단계와 드래그 상태 같은 클라이언트 상태를 분리했습니다.
  • TanStack Query: 관광지, 숙소, 일정 조회 캐시와 요청 조건 제어를 담당하게 했습니다.
02

고려한 대안과 Trade-off

  • 직접 구현한 Drag & Drop은 자유도가 높지만, 제스처 충돌과 layout 측정 책임이 커집니다.
  • 지도 탐색은 외부 지도 SDK와 디바이스 성능 영향을 받기 때문에 boundary와 요청 조건으로 비용을 제한했습니다.
  • Profiler 수치는 동일한 로컬 시나리오의 전후 비교이며 실제 사용자 기기 전체의 성능을 대표하지 않습니다.