pile·
프론트엔드·마켓컬리마켓컬리 Hello World·

뷰티 필터를 개발하며 얻은 새로운 경험 - React Query 도입기

컬리몰 뷰티컬리 필터 프로젝트를 진행하며 서버 상태 관리를 redux에서 React Query로 전환한 프론트엔드 경험을 다룬다. 실시간 재고·가격 변동을 반영하고 불필요한 API 호출을 줄이는 게 목표였고, 필터 도입으로 고객이 상품을 고르는 위치가 평균 32번째에서 19번째로 앞당겨졌다.

핵심 포인트
  • 안드로이드에만 있던 필터를 PC·모바일 웹으로 확장해 플랫폼 간 분산된 탐색 경험을 통일했다.
  • redux는 API 요청마다 action·reducer가 늘어 복잡도가 높았고, 오래된 화면이 옛 데이터를 보여줘 품절 시 구매 실패가 잦았다.
  • React Query로 전환해 서버 상태 캐싱·동기화·재요청을 hook으로 처리하고 불필요한 API 호출을 방지했다.
  • 서버 캐싱 5분보다 짧은 stale time 1분을 설정해 재고·가격 최신성을 확보했다.
  • 필터 상태를 URL에 저장해 새로고침·재방문 시 유지·공유가 가능하게 개선했다.
상세 정리
  • 두 가지 목표: 고객 측은 탐색 경험 개선(플랫폼 통일), 기술 측은 서버 데이터 상태 관리 방식 전환이었다.
  • redux 한계 구체화: 서버 응답 데이터를 전역 redux에 저장해 앱 전역에서 관리했는데, API 요청마다 여러 action·reducer가 필요해 코드 복잡성이 오르고 가독성이 떨어졌다. 또한 한 화면을 오래 띄우거나 다른 페이지 방문 후 재접속하면 옛 데이터를 노출해, 구매 가능으로 보고 장바구니에 담아도 실시간 품절로 구매에 실패하는 불편이 잦았다.
  • 의사결정 장치: 팀의 웹 개발 기술 선정 토론회에서 근거 문서·사전 학습·토론을 거쳐 민주적으로 React Query 도입을 결정했다. 팀원 전체에 영향을 주는 기술은 누구든 근거 문서로 안건을 제기하고 학습을 공유한 뒤 토론으로 도입 여부를 정한다.
  • React Query 정의: 서버 상태를 불러오고 캐싱·동기화·업데이트하는 hook 기반 라이브러리로, 비동기 데이터 관리에 특화돼 redux보다 요구사항을 빠르게 충족한다.
  • 전환 방식: 필터 프로젝트를 전환의 초석으로 삼아 전역 공통 설정부터 팀에 사전 공유해 병렬 프로젝트와 혼선을 막고, 기존 redux 데이터와 분리하며 상태 유지 시점을 재설계했다.
  • stale time 설계: 서버도 자체 캐싱하지만 그 값을 가져오는 통신 비용을 고려해, 서버 캐싱 5분보다 짧은 1분으로 설정해 최신 정보 제공과 호출 절감을 절충했다.
  • 성과(고객): 필터 배포 후 한 달 분석에서 상품 선택 위치가 평균 32번째에서 19번째로 개선돼, 원하는 상품을 더 상단에서 결정하게 됐다.
  • 성과(기술): 필터 적용·해제 시 발생할 다수 API 호출을 React Query 캐싱으로 방지하고, 화면 이탈 후 복귀 시에도 빠르게 새 데이터를 받게 됐다.
  • 부가 개선: 필터 결과를 URL에 저장해 상태를 유지·공유하고, 모바일 웹 검색 키워드 하이라이트를 웹팀이 자발적으로 제안·개발했다.
왜 읽나redux에서 React Query로 서버 상태 관리를 옮기려는 프론트엔드 개발자에게 전환 동기·stale time 튜닝·URL 상태 저장의 실무 판단을 보여주는 사례.
마켓컬리
마켓컬리 Hello World 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·LINE EngineeringLINE Engineering·

    AI로 웹 엔지니어 없이 LINE 앱 안에서 그룹 영상 통화 서비스 만들기

    LINE Planet 팀의 PM과 Android 엔지니어 두 명이 웹 전문 엔지니어 없이 LINE 앱 내에서 그룹 영상 통화 서비스를 개발한 과정을 다룬다. LIFF(LINE Front-end Framework)와 LINE Planet SDK를 활용해 React/Vite 기반 웹 앱을 구성했고, Firebase Cloud Functions로 별도 서버 인프라 없이 구현을 완료했다.

    #react#webrtc#firebase+2