-
Notifications
You must be signed in to change notification settings - Fork 4
쿼리 캐싱을 이용한 서버 상태관리
리액트 쿼리의 서버 상태 관리 및 캐싱 기능에 영감을 받아 이 기능만 직접 구현해보았습니다.
이 시스템의 핵심은 Zustand를 사용해 만든 캐시 스토어입니다. 이 스토어는 서버에서 가져온 데이터를 캐싱하고, 데이터의 최신 여부를 관리하는 역할을 합니다.
캐시는 간단한 객체로 구성되며, 각 키는 고유한 데이터 식별자(예: 쿼리 키)와 연결됩니다. 각 캐시 항목은 다음 정보를 포함합니다:
-
data: 서버에서 가져온 실제 데이터.
-
timestamp: 데이터를 캐싱한 시간.
-
staleTime: 데이터가 "오래된" 것으로 간주되기까지의 시간(기본값: 5분).
캐시 스토어는 데이터를 관리하기 위한 몇 가지 메소드를 제공합니다:
- setCache(key: string, data: any, staleTime?: number) 주어진 key에 데이터를 캐싱합니다. 현재 시간(timestamp)과 staleTime(기본값: 5분)을 함께 저장합니다.
- getCache(key: string) 캐시에서 데이터를 가져옵니다. 데이터가 존재하고, 캐싱된 이후 staleTime을 초과하지 않았다면 데이터를 반환합니다. 만약 데이터가 오래되었다면 해당 캐시를 무효화하고 null을 반환합니다.
- invalidateCache(key: string) 특정 key에 해당하는 캐시 항목을 삭제합니다. 데이터가 변경되었을 때 사용합니다. ex) socket 을 통한 실시간 데이터가 반영되야 할때.
- invalidateQueries(prefix: string) 주어진 prefix로 시작하는 모든 캐시 항목을 삭제합니다. 예를 들어, 사용자의 프로필 정보를 갱신한 후 프로필과 관련된 모든 쿼리를 무효화할 때 유용합니다.
캐시 스토어를 React 컴포넌트에서 쉽게 사용할 수 있도록 useQuery라는 커스텀 훅을 만들었습니다. 이 훅은 React Query의 API를 참고하여 설계되었지만, 더 간단하게 구현되었습니다.
useQuery 훅은 세 가지 파라미터를 받습니다:
- queryKey: string 쿼리를 식별하는 고유한 키. 캐시 키로 사용됩니다.
- queryFn: () => Promise 서버에서 데이터를 가져오는 비동기 함수(프로미스를 반환).
-
options: QueryOptions
선택적으로 설정할 수 있는 옵션 객체. 포함 가능한 속성은 다음과 같습니다:
- staleTime: 데이터가 오래된 것으로 간주되는 시간(기본값: 5분).
- enabled: 쿼리가 자동으로 실행될지 여부(기본값: true).
- onSuccess: 데이터가 성공적으로 가져와졌을 때 호출될 콜백 함수.
- onError: 데이터 가져오기에 실패했을 때 호출될 콜백 함수.
훅은 두 가지 상태를 관리합니다:
- isLoading: boolean 데이터가 현재 가져오는 중인지 여부를 나타냅니다.
- error: any 데이터 가져오기에 실패했을 때 발생한 에러를 저장합니다.
-
fetchData(skipCache = false) 데이터를 가져오는 주요 함수입니다. 동작 방식은 다음과 같습니다:
-
skipCache가 false(기본값)일 경우, 먼저 캐시에서 유효한 데이터를 확인합니다. 유효한 데이터가 있다면 즉시 반환하고 onSuccess 콜백을 호출합니다.
-
캐시에 유효한 데이터가 없거나 skipCache가 true라면, 데이터 가져오기를 시작합니다. 데이터를 성공적으로 가져오면 캐시에 저장하고 onSuccess를 호출합니다.
-
에러가 발생하면 error 상태를 설정하고 onError를 호출합니다.
-
-
refetch() 캐시를 무시하고 데이터를 다시 가져오는 함수입니다. 예를 들어, 사용자가 버튼을 눌러 데이터를 갱신할 때 유용합니다.
훅은 useEffect를 사용해 자동으로 데이터를 가져옵니다. 자동 실행 조건은 다음과 같습니다:
- 컴포넌트가 마운트될 때.
- enabled 값이 변경될 때(enabled가 true라면 데이터를 가져옵니다).
- queryKey가 변경될 때(다른 쿼리로 전환된 경우).
또한, useRef를 사용해 컴포넌트가 언마운트된 후에도 상태 업데이트를 방지합니다.
- 탭바 슬라이딩 애니메이션으로 전환하기
- Presigned url 을 통한 이미지 업로드
- 입력 크기에 맞춰 늘어나는 textarea만들기
- flex:1를 사용할 때 부모 컴포넌트의 사이즈를 넘어가는 현상
- 위아래로 채팅 무한 스크롤 구현하기
- 공통 컴포넌트 문서화를 통해 UI 재사용성 향상
- 전역적 소켓 관리
- 쿼리 캐싱을 이용한 서버 상태 관리
- 전역 에러 처리
- 모바일 호환성을 위한 노력
- 기술 선정 이유
- 아키텍처
- 답해요 채팅 저장 방식 고민(데이터베이스 고민)
- 말해요 채팅 저장 방식 고민
- MongoDB에서 답해요와 말해요 채팅 데이터 관리 및 샤드 설계
- 웹소켓 연결 방식 고민
- MongoDB 인덱스 유무에 따른 쓰기, 조회 성능 테스트
- 중복 웹소켓 세션 처리 전략 및 구현 결정
- @Async를 활용한 이메일 전송 비동기 처리 및응답 시간 개선
- Docker 환경에서 ClassPathResource.getFile()이 실패하는 문제 해결
- Redis sync vs Async
- MongoClient vs Spring Data MongoDb
- 채팅방 웹소켓 이벤트 정리
- 무한 스크롤 정리
- 중복 로그인 방지
- 이미지 업로드 분리 및 비동기화
- 채팅 전송 도중 채팅방이 삭제된다면?
- 금칙어 필터링
- 답해요 성능테스트
- 새로 개설된 말해요 채팅방 실시간으로 알리기