문제 상황
분명히 react-query에서 client를 getQueryClient로 잘 가져오고 있는데 onSuccess가 제대로 동작하지 않는다...진짜 왜일까 진짜로...
라고 생각하던 차!
개발 일지를 작성하며 추측했던 몇 가지 요소대로 이유를 추려나가기로 마음 먹었다.
이렇게 원인인 것 같은 부분을 점차 좁혀나가자, 결국엔 원인을 찾아냈다 하하 !
아래는 문제 해결 전에 작성했던 코드이다.
문제와 관련없는 부분은 생략했다
'use client'
function EditProfileModal({ openModal, handleModalClose, profileData }: EditProfileModalProps) {
const queryClient = getQueryClient(); //이 부분이 올바르게 동작하지 않는 것으로 추정
const nickNameValue = useTextInput();
const aboutMeValue = useTextInput();
const changeProfileMutation = useMutation({
mutationFn: (newProfileData: PutUserDataType) => {
return profileAPI.putUserData({ userId: profileData.id, userData: newProfileData });
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["profile", profileData.id.toString()],
});
handleModalClose();
},
});
const handleCompletedProfile = (event: FormEvent<HTMLFormElement | HTMLButtonElement>) => {
event.preventDefault();
// 생략...
changeProfileMutation.mutate(submitData); //이 mutation이 success되면 onSuccess가 동작해야 함
};
return (
<Modal openModal={openModal} handleModalClose={handleModalClose}>
// 생략 ...
</Modal>
);
}
export default EditProfileModal;
이유 추측 1
tanstack/react-query대신 react-query에서 import해서 !?
: tanstack/react-query로 써야하는 걸 몇 군데에서 react-query로 import 해서 사용하고 있다는 것을 알았다.
하지만, import 문을 올바르게 변경해도 여전히 onSuccess는 동작하지 않았다.
=> queryClient provider를 인지하지 못하는 에러는 해결할 수 있었다.
이유 추측 2
queryKey의 문제인가!?
queryKey : [`profile-${userId}`]
->
queryKey : ["profile", userId]로 변경
No! 바꿨는데도 안 되고 잘못된 부분도 없고, console에 찍어보았을 때도 완벽히 일치한다는 것을 알 수 있었다.
이유 추측 3 - [ 원인 발견 * ]
onSuccess 안에 있는 handleCloseModal 함수는 잘 동작하는 것으로 보아, onSuccess 상태를 캐치하지 못하는 것은 아니다.
그렇다면 에러가 발생하는 범위를 좁혀나갈 수 있다 -> 범인은 바로 queryClient 바로 너!?
해결법
getQueryClient 대신 useQueryClient를 사용하자 잘 된다 !
getQueryClient와 useQueryClient의 차이점
우선, 이 두가지는 모두 QueryClient를 얻기위한 방법이라는 공통점을 갖고 있기 때문에 나와 같은 실수를 누군가는 할 것이라고 생각한다.
이 두 함수의 차이점은 사용하는 상황으로 설명할 수 있다.
useQueryClient는 React-Hook중 하나로, 일반적인 React 컴포넌트 내부에서 queryClient를 가져오기 위해서 사용한다.
그렇다면 getQueryClient는 뭐가 다르기에, 나의 코드에서 동작하지 않았던 것일까?
getQueryClient는 우선 React-Hook이 아니고, 주로 React Context 외부에서 QueryClient 인스턴스에 접근할 때 사용한다.
이걸 보고 나는 아...하고 한숨이 나왔다. hook이 아니다? 그렇다.
나는 Next.js의 앱 라우터를 사용하고 있었기 때문에 처음부터 getQueryClient를 사용하고 있었던 것이다.
분명히 처음에는 서버 컴포넌트에서 react-query를 사용해서 데이터를 패칭하려면 어떻게 해야하지? 하고 알아보고 사용했던 것이었는데, 제대로 이해하지 않고 사용법부터 바로 적용하다보니 클라이언트 컴포넌트로 전환했을 때 빠르게 문제를 인식할 수 없었다.
이제는 차이점과 문제의 원인도 알았으니, 마지막으로 한 번 더 저 둘의 차이점을 정리하고 마무리하도록 하겠다.
getQueryClient | useQueryClient | |
사용 상황 | 컴포넌트 내부에서 queryClient에 접근하고 싶을 때 사용 | |
React hook | X | O |
용도 | 서버 사이드 렌더링(SSR) 환경이나 React 컴포넌트가 아닌 곳에서 QueryClient에 접근하기 위해 사용 |
컴포넌트 내에서 QueryClient 인스턴스를 가져오고 사용하기 위해 사용 |
Next.js 환경에서 QueryClient를 사용하는 법도 확실히 알았고, 잊지 못할 것 같다 하하하하하핳
따지고 보면 큰 오류는 아니었지만,
어디에서 내가 의도하지 않은 코드를 작성하고 있는지 범위를 좁혀나가는 과정이 의미있다고 생각한다.
앞으로도 어딘가에서 오류가 발생하면, 차근차근 이유를 추측하고 범위를 좁혀서 찾아나갈 수 있을 것 같다.
그럼 오늘은 이만 -
안뇽 !
'🗂️ 개발 이모저모' 카테고리의 다른 글
[타임세이버] query-key 줍다 지친 사람 여기 여기 붙어라 (with. query-key-factory) (0) | 2024.08.22 |
---|---|
[FeedB] 무한 스크롤 구현 (with. App router & react-query) (0) | 2024.07.26 |
[FeedB] 기획 소개 및 컨벤션 (feat.구현계획) (0) | 2024.06.17 |
[React] key값으로 index를 쓰지 말라고? with.UUID (4) | 2024.06.04 |
[CSS] Box Model (1) | 2024.05.29 |