-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FE] api 호출 개선 : 지출 내역 과정 #923
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
역시 리액트 쿼리 장인 쿠키.. 엄청나게 api 요청이 줄었네요! 서버 비용이 지금보다 더 줄을 것 같아서 너무 죻습니댜!
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.reports]}); | ||
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.currentMembers]}); | ||
onSuccess: (_, {billId}) => { | ||
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.steps, eventId]}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
queryKey가 [QUERY_KEYS.steps, eventId]와 같이 eventId가 두번째 배열의 값으로 들어가게 된 이유가 eventId를 변수로 사용하여 관리하는 것이기 때문인가요?.?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 PR에서 이유를 알게 되었어요!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
invalidateQueries가 QueryKey를 찾는 조건을 추가해준 것입니다. 특정 event id 캐시만 무효화한 것이라고 생각해주시면 됩니다
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.steps, eventId]}); | ||
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.reports, eventId]}); | ||
|
||
// admin으로 navigate 되기 전 invalidate 실행 시 api를 불러오는 문제 발생 => remove를 사용하여 캐시 데이터 삭제하는 방식으로 해결s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마지막에 오타있어요..!(소곤)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엇 수정해서 올렸습니다~
* refactor: 지출 추가할 때 invalidate queries 남용으로 인해 불필요한 api 호출했던 현상을 개선 * feat: 인원 추가되는 상황에서 post bill이 호출된 후에 all members 무효화 * refactor: post members에 all members invalidate 옮기는 것으로 수정 * style: 불필요한 import 제거 * style: success 오타 수정 * refactor: 지출내역 수정과 상세 수정은 현재 인원을 변동시키지 않으므로 current invalidate 제거 * refactor: 지출내역 삭제할 때는 다시 지출내역 상세를 확인할 수 없으므로 캐시데이터 삭제 * fix: invalidate queries querykey에 event id 추가 * fix: invalidate queries의 query key event id 추가 * style: 주석 오타 수정
issue
문제 상황
지출 내역 추가
개선 전
개선 전의 모습을 보면 지출 내역 추가 시 api 호출이 총 5번이 일어나는 모습을 확인할 수 있고 그 중 current api는 두 번 요청되는 모습을 확인할 수 있습니다. 이 문제를 발견 후 각 페이지 별 캐시 상태를 비교해봤습니다. (위 세 번째 사진 참고)
여기서 주목할 데이터는
currentMembers
입니다. 지출 내역 추가 후 관리 페이지로 이동한 후에는 currentMembers 데이터가 필요하지 않지만 두 번이나 서버로 요청을 보내는 문제가 있었습니다.문제 원인
useRequestPostMembers와 useRequestPostBill hook에서 mutate 실행 후 invalidate를 해주는 과정에서 불필요한 api가 호출되었습니다.
우선 invalidateQueries가 실행된 후 언제 서버로 api를 호출하는지 설명하겠습니다. invalidateQueries는 캐시 데이터를 fresh에서 stale상태로 무효화 시켜줍니다. 그러면 데이터가 상했으니 서버로부터 최신 데이터를 불러오게 됩니다. 여기서 서버로 요청을 보내는 조건은 캐시 데이터가 active할 때입니다. 캐시 데이터가 active하는 것은 현재 마운트 되어있는 컴포넌트에서 사용하는 데이터입니다.
이 점을 인지한 상태로 아래 코드를 보면 문제를 알 수 있습니다.
먼저 handlePostBill가 실행되면 postMembersAsync이 실행된 후 onSuccess가 실행되어 allMembers, steps, reports, currentMembers 캐시 데이터가 무효화됩니다. 그 다음으로 postBill이 실행된 후 onSuccess가 실행되어 steps, reports, currentMembers 캐시 데이터가 무효화됩니다. 마지막으로 isSuccessPostBill 상태가 true가 되어 그제서야 관리 페이지로 이동합니다.
currentMembers
를 특정해서 문제 상황을 살펴보면 postMembersAsync가 실행된 후 요청이 성공해서 currentMembers가 무효화 되었습니다. 이 순간은 페이지 이동하기 전이라 currentMembers 데이터가 active합니다. 그래서 즉시 서버로 currentMembers 요청을 보내게 됩니다. 그 후 postBill이 실행되고 요청이 성공하여 currentMembers가 무효화 되었습니다. 이 순간도 페이지 이동하기 전이라 currentMembers 데이터가 active합니다. 그래서 즉시 서버로 currentMembers 요청을 보내게 됩니다. 마지막으로 isSuccessPostBill 상태가 true가 되어 그제서야 관리 페이지로 이동하게 됩니다. 하지만 관리 페이지에서는 currentMembers 데이터가 inactive한 상태입니다.해결 방법
우선 postMembersAsync mutation의 onSuccess에서 currentMembers invalidate를 지워줬습니다. postMembersAsync는 항상 postBill 전에만 실행이 되기 때문에 문제 없다고 판단했습니다.
그 다음으로 useRequestPostBill에서 currentMembers를 invalidateQueries에서 removeQueries로 바꿔줬습니다.
여기서는 단순히 코드를 지우지 않고 변경해 준 이유는 지출 내역 추가가 됐음에도 currentMembers 상태가 변하지 않는다면 다음 지출 내역을 추가할 때 영향이 생길 수 있기 때문입니다. 처리는 해줘야 하지만 invalidateQueries를 사용하면 stale로 변하고 현재 데이터가 active하기 때문에 바로 서버로 요청이 갑니다. 이 때 removeQueries를 사용해서 캐시 데이터를 아에 지워버린다면 서버로 요청하는 시점을 다음 지출 내역 추가로 미룰 수 있게 됩니다. (캐시 데이터를 아예 삭제했으므로 currentMembers 캐시 상태는 stale도 아니게 돼서 다시 요청도 하지 않는 원리)
개선 결과
불필요한 currentMembers 요청을 두 개 줄이게 되어 get 요청을 이전 5번에서 3번으로 api 호출을 줄일 수 있었습니다.
지출 내역 수정
개선 전
내역 수정 후 지출 내역을 추가할 때 비효율이 발생합니다.
지출 내역을 수정하는 것은 현재 참여 인원의 변동을 일으키지 않습니다. 금액과 차등 정산만 가능하기 때문입니다.
하지만 지출 내역을 수정할 때 currentMembers 캐시 데이터를 무효화해서 지출 내역을 추가할 때 다시 api를 호출합니다.
해결 방법
put과, put detail hook onSuccess 아래 코드를 제거했습니다.
개선 결과
지출 내역을 수정 후 등록할 때 current api를 새로 보내지 않아도 돼서 current api 호출 수 1개를 줄였습니다.
🫡 참고사항
지출 내역 삭제할 때 지출 상세 캐시 데이터 삭제
지출 내역이 삭제되면 더 이상 지출 상세 캐시 데이터를 가지고 있을 필요가 없습니다. 더 이상 호출될 일이 없기 때문입니다.
그래서 캐시 데이터를 삭제하는 removeQueries를 호출하여 캐시 데이터를 지웠습니다.