일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 클래스
- DeleteAll
- 주간회고
- Jenkins
- java
- ci/cd
- 도커
- 블로그 병행
- 월간회고
- BalancedTree
- 프리코스
- SQL 실행순서
- db
- useMutation
- 멀티쓰레드 프로그래밍
- Blue-Green
- 기능별 구조
- N+1
- 백기선 스터디
- 카카오 2차 코딩테스트
- 우테코
- mysql
- 회고
- useQuery
- 계층별 구조
- 메서드명
- InnoDB 버퍼 풀
- B+TREE
- 어댑티브 해시 인덱스
- jacoco
- Today
- Total
Haneul's Blog
[스케줄 관리 프로젝트 - 일치(FE)] 캐싱을 도와주는 useQuery, useMutation 본문
프론트 캐싱에 관한 고민
일정 관리 스케줄에서 스케줄들을 호출할 떄 아래와 같이 달을 이동할 때 api를 호출하는 방법을 사용하다보니 프론트쪽에서 캐싱을 하지 않으면 만약에 3월에서 4월로 이동하고 다시 4월에서 3월로 이동할 때 한 번 더 api 호출하게 되어 불필요하게 3월을 두 번 호출하게 되는 문제가 있었습니다.
위의 사진을 보면 3월달 화면을 로딩시에 api를 최초 1회 요청하는 것을 보실 수 있습니다.
그리고 4월달로 이동하면 다시 4월달의 일정 api를 최초 호출하는 것을 보실 수 있습니다.
그런데 위의 마지막 사진을 보시면 3월달로 다시 돌아갔을 때 api 호출이 불필요하게 한 번 더 되는 것을 볼 수 있습니다.
이 문제를 해결하기 위해서는 한 번 호출했던 데이터를 일정 시간동안 캐싱하는 방법을 사용하면 되는데, 이를 위해서 필요한 게 어떤게 있을까 찾아보다가 발견 한 것이 useQuery와 useMutation이 있었습니다.
useQuery
useQuery는 서버로부터 데이터를 조회(get)해올 때 사용하게 되는데 useQuery를 잘 사용하기 위해서는 queryKey와 queryFn을 알고 있어야 합니다.
queryKey
queryKey는 useQuery마다 부여되는 고유 key값으로 캐싱되는 데이터들의 키라고 생각하면 이해하기 쉽습니다.
이는 문자열과 배열의 형태로 사용될 수 있습니다.
const schedules1 = useQuery({
queryKey: 'schedules'
});
const schedules2 = useQuery({
queryKey: ['schedules','3']
});
queryFn
queryFn은 간단하게 설명하자면 실제 서버에 api 요청을 하는 코드라고 생각할 수 있습니다.
const schedules1 = useQuery({
queryKey: 'schedules'
queryFn: () => getSchedulesApi(),
});
const schedules2 = useQuery({
queryKey: ['schedules','3']
queryFn: () => getSchedulesApi(),
});
이렇게 queryKey와 queryFn을 통해서 간단하게 서버에서 데이터를 가져와서 캐싱을 할 수 있습니다.
하지만 또 하나의 문제가 발생할 수 있는데 일정을 관리하는 사람이 여러 명일 경우 다른 사람이 스케줄을 생성, 수정, 삭제를 할 경우가 있을 것입니다.
그렇게 되면 캐싱해둔 데이터와 추가, 삭제, 수정된 데이터의 정합성이 어긋나는 경우가 생길 수 있기 때문에 useQuery에는 또 다른 기능이 있습니다. 바로 staleTime과 cacheTime라는 기능입니다.
먼저 staleTime은 이름 그대로 신선하지 않은 시간을 의미하며 stale하다는 것은 오래된 데이터로 정합성이 어긋나있을 수 있다는 것입니다. 그렇기 때문에 staleTime을 설정해두고 설정한 시간이 지나면 데이터가 stale해졌다고 판단하여 다시 데이터를 불러오도록 할 수 있게 해줍니다.
그리고 cacheTime은 말 그대로 데이터가 캐싱되는 시간을 의미하며 staleTime이 cacheTime 시간보다 크다면 데이터가 캐싱되지 않는 시간대가 생길 수 있습니다. 그렇기 때문에 기본적으로 시간 설정을 staleTime <= cacheTime으로 해주는 것이 좋습니다.
const schedules1 = useQuery({
queryKey: 'schedules'
queryFn: () => getSchedulesApi(),
staleTime: 10000,
cacheTime: Infinity,
});
const schedules2 = useQuery({
queryKey: ['schedules','3']
queryFn: () => getSchedulesApi(),
staleTime: 10000,
cacheTime: Infinity,
});
위의 내용인 useQuery는 데이터를 호출(get)할 때 사용 되는 것이고, 만약에 내가 데이터를 삭제(delete), 수정(put, patch), 생성(post)하고 데이터를 다시 호출하지 않고 캐싱되어 있는 데이터를 사용하게 되면 서버 DB에 있는 데이터와 캐싱되어 있는 데이터의 정합성이 깨지기 때문에 캐싱되어 있는 데이터를 삭제할 필요가 있습니다.
이를 위해서 존재하는 것이 useMutation입니다.
useMutation
위에서 설명했다시피 데이터 변경 작업을 요청할 때 사용하는 것으로 이를 사용하기 위해서는 기본적으로 몇 가지를 알고 있어야 합니다.
mutationFn
먼저 서버에 api요청을 할 수 있게 해주는 mutationFn이 있고, useQuery의 queryFn과 비슷하다고 생각하면 쉽습니다.
const schedule = useMutation({
mutationFn: (body) => postSchedulesApi({ body })
});
mutate
그리고 mutate가 있는데 먼저 mutate는 작성한 내용이 실행될 수 있도록 트리거 역할을 해주며, useMutation을 먼저 정의해두고 실제 데이터를 변경 작업을 요청하고 싶다면 mutate를 사용하면 됩니다.
const { mutate } = useMutation({
mutationFn: (body) => postSchedulesApi({ body })
});
mutate(body); // 데이터 저장
onSuccess, onError, onSetteld
onSuccess, onError, onSetteld는 각 이름 그대로 변경 작업 성공, 실패, 성공하던 실패하던 api 호출을 하고 나서 실행하게 해주는 키워드라고 생각하면 쉽습니다.
invalidateQueries
마지막으로 invalidateQueries라는 것이 있는데, 아까 useMutation을 설명하기 전에 캐싱을 하면 생길 수 있는 문제에 대해서 잠깐 설명했었는데, 이를 invalidateQueries가 해결해줄 수 있습니다.
invalidateQueries는 useQuery의 queryKey의 유효성을 제거해주는 목적으로 사용되고, 데이터를 변경시키면서 데이터의 정합성을 맞추기 위해서 서버로부터 다시 데이터를 조회하기 위해서 사용됩니다. 만약 invalidateQueries를 사용하지 않고 캐싱되어 있는 데이터를 사용하게 되면 아까도 설명했다시피 DB의 데이터와 캐싱된 데이터의 정합성이 깨지기 때문에 서버에서 데이터를 다시 조회해와야 합니다.
const queryClient = useQueryClient();
const { mutate } = useMutation(body => postSchedulesApi({ calendarId, body }), {
onSuccess: () => {
queryClient.invalidateQueries('schedules');
},
});
'일정 관리 프로젝트(일치)' 카테고리의 다른 글
[스케줄 관리 프로젝트 - 일치(INFRA)] Jenkins를 활용한 CI/CD(2) - Backend CI/CD 환경 구축 및 사용 (0) | 2023.05.03 |
---|---|
[스케줄 관리 프로젝트 - 일치(INFRA)] Jenkins를 활용한 CI/CD(1) - 설치 과정 (0) | 2023.05.03 |
[스케줄 관리 프로젝트 - 일치(INFRA)] 성능 테스트 준비 과정 (0) | 2023.05.01 |
[스케줄 관리 프로젝트 - 일치(BE)] Spring 단위 테스트 (0) | 2023.04.20 |
[스케줄 관리 프로젝트 - 일치(BE)] 프로젝트 패키지 구성에 관한 고민 (0) | 2023.03.21 |