시공관리 협업툴 크로스팀 서비스 개발
기술 스택 : React / TypeScript / Redux Toolkit / React Query / Styled Components / Ant Design
*소개
크로스팀은 시공 프로젝트를 관리할 수 있는 서비스로 건설현장에서 시공, 감리와 같은 업체들이 서로 정보를 공유하고 문서작성과 전자결재와 같은 업무를 협업해서 진행할 수 있는 기능을 제공합니다.
*담당한 업무
**리액트 쿼리(React Query) 도입 후 서버 상태와 클라이언트 상태 분리
- 기존에는 Redux Toolkit으로 상태 관리와 비동기 처리를 함께 했습니다. 하지만 리덕스와 같은 전역 상태 관리 도구를 사용해서 비동기 처리를 함께하다 보니, 전역 상태가 API 통신과 엮기게 되고 비동기 로직이 추가되면서 Store가 비대해지는 문제가 발생했습니다.
- 이러한 이유로 서버 상태와 클라이언트 상태를 분리해주기 위해 서버 상태 관리 라이브러리인 리액트 쿼리(React Query)를 도입하게 되었습니다. 기존의 서버 상태와 관련된 API 통신을 리액트 쿼리로 대체하였고, 도메인 별로 쿼리를 관리해주었습니다.
- 리액트 쿼리 도입 후 클라이언트와 서버 상태를 분리할 수 있었습니다. Store에는 클라이언트에서 제어할 수 있는 데이터만 남기고 API 통신과 관련된 로직을 제거했습니다. 그리고 리액트 쿼리에서 제공하는 캐싱 기능을 통해 서버의 데이터 요청을 효율적으로 처리할 수 있었습니다.
**타입스크립트(TypeScript) 도입
- 개인적으로 진행한 프로젝트에서 타입스크립트를 사용 했을 때 자동완성 및 타입 체크로 인해 개발 생산성을 높일 수 있을 뿐 아니라 자바스크립트에는 없는 Interafce, Generic과 같은 기능이 제공되기 때문에 더 객체 지향적으로 코드를 작성할 수 있다는 것을 알게되었고, 이러한 장점을 활용하기 위해 타입스크립트를 도입하였습니다.
- 타입스크립트에서 제공하는 Interface를 사용해서 상속이 아닌 컴포지션(Composition) 방식으로 클래스 간에 서로 상호작용할 수 있도록 변경해주었고 이를 통해 클래스 간의 밀접하게 Coupling 되어 있는 문제를 해결할 수 있었습니다.
**Code Splitting과 이미지 Preloading을 이용한 성능 최적화
- 사용자가 Modal 창을 열었을 때 업로드한 사진들을 보여주는 기능을 개발하는 과정에서 이미지가 늦게 보여지는 문제가 있었습니다. Modal 컴포넌트 내부에 Modal을 구현하기 위한 외부 라이브러리를 사용하고 있었기 때문에, Modal 창을 열기 위한 버튼을 클릭했을 때 Code Splitting을 통해 동적으로 Modal 컴포넌트를 불러올 수 있도록 구현을 한 상태였습니다.
- 처음에는 Modal 컴포넌트가 포함된 컴포넌트가 마운트 된 다음, Modal창을 열기 위한 버튼을 클릭하기 전에 Modal 컴포넌트를 동적으로 import해서 불러올 수 있도록 코드를 수정했습니다. 하지만 이렇게 코드를 수정한 이후에도 이미지가 늦게 보여지는 문제가 해결되지 않았습니다. Modal 창을 열었을 때 이미지를 요청하는 것을 네트워크 패널에서 확인한 후, Modal 관련 코드 뿐 아니라 이미지도 함께 Preload 하는 방식으로 문제를 해결했습니다.
- 컴포넌트가 마운트 되었을 때 자바스크립트 이미지 객체를 생성한 다음, src 속성에 이미지 주소를 넣어주는 방식으로 필요한 이미지를 미리 불러오도록 처리했고, 이를 통해 Modal 창을 열었을 때 이미지가 늦게 보이는 문제를 해결할 수 있었습니다
**PG사 연동을 통한 서비스 결제 기능 개발
- 결제 연동 가이드에 따라 public 폴더 내의 index.html 에 결제 연동을 위해 필요한 script를 선언해주었을 때 결제 페이지에 접속하지 않아도 자바스크립트 파일을 불필요하게 다운로드 받는 문제가 있었습니다.
- 이러한 문제를 해결하기 위해 라우트 기반 코드 분할(Route-based code splitting)을 적용했습니다.
- 결제 연동을 위해 필요한 script 태그를 결제 관련 컴포넌트 내부에 선언해서 결제 페이지에 접근했을 때 동적으로 결제 연동을 위한 script를 불러올 수 있도록 처리했습니다.
**인증(Authentication), 인가(Authorization) 관련 기능 개발
- 처음에는 로그인, 회원가입, 가입정보 페이지에 사용되는 Button과 Input 컴포넌트가 페이지 별로 각각 선언되어 있었습니다.
- 컴포넌트의 디자인과 역할이 크게 다르지 않았기 때문에 여러 유즈 케이스에 대응할 수 있는 공통의 Button, Input 컴포넌트를 정의한 다음 필요한 페이지에서 해당 컴포넌트를 불러와서 사용할 수 있도록 수정했습니다.
- HOC 방식을 사용해서 페이지별로 접근 권한을 설정해주었습니다.
** 오프셋 기반 페이지네이션 기능 프론트엔트 개발
- 처음에는 생성된 모든 프로젝트 정보를 서버에서 전달받아 페이지네이션이 적용된 테이블 형태로 보여주었습니다.
- 하지만 생성된 프로젝트 수가 늘어날수록 데이터를 받는 시간이 오래 걸렸고, 새로고침시 선택한 페이지 정보가 사라지기 때문에 첫번째 페이지로 이동하게 되는 문제가 있었습니다.
- 이러한 문제를 해결하기 위해 오프셋 기반 페이지네이션을 적용했습니다.
- 사용자가 현재 테이블에서 보여줄 데이터 개수를 변경하거나 페이지를 이동할 때 마다 offset과 테이블에서 보여줄 데이터 개수가 포함된 url이 바뀌도록 했고, 해당 url 값을 이용해서 데이터를 다시 요청해서 보여주는 방식으로 처리해주었습니다.
더보기