Skip to content

Commit aef6d87

Browse files
authored
Merge pull request #214 from prgrms-web-devcourse-final-project/fix/213-post-delete
[fix] 게시글 삭제 버그 수정
2 parents df96da8 + 973160b commit aef6d87

File tree

2 files changed

+64
-49
lines changed

2 files changed

+64
-49
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query';
2+
import { deleteEmotionRecord } from '@/apis/emotionRecord';
3+
4+
export const useDeleteEmotionRecord = (userId: string) => {
5+
const queryClient = useQueryClient(); // useMutation 사용
6+
7+
return useMutation({
8+
mutationFn: (recordId: number) => deleteEmotionRecord(recordId),
9+
onMutate: async (recordId) => {
10+
// 낙관적 업데이트 전에 사용자 목록 쿼리를 취소해 잠재적인 충돌 방지!
11+
await queryClient.cancelQueries({
12+
queryKey: ['emotionRecords', userId],
13+
});
14+
15+
// 캐시된 데이터(사용자 목록) 가져오기!
16+
const previousRecords = queryClient.getQueryData<InfiniteData<EmotionRecordPages>>([
17+
'emotionRecords',
18+
userId,
19+
]);
20+
21+
// 기존 데이터 확인 (없으면 오류 발생 방지)
22+
if (!previousRecords?.pages) {
23+
console.error('❌ 기존 데이터가 없습니다.');
24+
throw new Error('기존 데이터 없음');
25+
}
26+
27+
// 기존 데이터를 기반으로 낙관적 업데이트 수행
28+
queryClient.setQueryData(
29+
['emotionRecords', userId],
30+
(oldData: InfiniteData<EmotionRecordPages>) => {
31+
return {
32+
...oldData,
33+
pages: oldData.pages.map((page: EmotionRecordPages) => ({
34+
...page,
35+
data: {
36+
...page.data,
37+
records: page.data.records.filter((r: EmotionRecord) => r.recordId !== recordId),
38+
},
39+
})),
40+
};
41+
},
42+
);
43+
44+
// 각 콜백의 context로 전달할 데이터 반환!
45+
return { previousRecords };
46+
},
47+
onError: (_, __, context) => {
48+
if (context?.previousRecords) {
49+
queryClient.setQueryData(['emotionRecords', userId], context.previousRecords);
50+
}
51+
},
52+
onSettled: () => {
53+
queryClient.invalidateQueries({
54+
queryKey: ['emotionRecords', userId],
55+
});
56+
},
57+
});
58+
};

src/pages/userprofile/UserProfile.tsx

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { deleteEmotionRecord, getUserEmotionRecords } from '@/apis/emotionRecord';
1+
import { getUserEmotionRecords } from '@/apis/emotionRecord';
22
import { getMyProfile, getUserProfile } from '@/apis/user';
33
import CardDetailModal from '@/components/modalSheet/CardDetailModal';
44
import MusicCard from '@/components/MusicCard';
55
import { useModalStore } from '@/store/modalStore';
66
import { useSheetStore } from '@/store/sheetStore';
7-
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
7+
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
88
import { useEffect, useState } from 'react';
99
import { useNavigate, useParams } from 'react-router';
1010
import { useInView } from 'react-intersection-observer';
1111
import EmotionRecordCardList from '@/pages/userprofile/components/EmotionRecordCardList';
1212
import { useUserStore } from '@/store/userStore';
1313
import Loading from '@/components/loading/Loading';
14+
import { useDeleteEmotionRecord } from '@/hooks/useDeleteEmotionRecord';
1415

1516
// 마이페이지 / 유저페이지 동시에 사용
1617
function UserProfile({ isMyPage }: { isMyPage: boolean }) {
@@ -19,7 +20,6 @@ function UserProfile({ isMyPage }: { isMyPage: boolean }) {
1920
const { userId } = useParams(); // 유저페이지 경우
2021
const { openSheet, closeSheet } = useSheetStore(); // 시트
2122
const { openModal, closeModal } = useModalStore(); // 모달
22-
const queryClient = useQueryClient(); // useMutation 사용
2323
const { setUserData } = useUserStore(); // 유저 정보 전역 저장
2424

2525
const { ref, inView } = useInView();
@@ -37,6 +37,7 @@ function UserProfile({ isMyPage }: { isMyPage: boolean }) {
3737
}
3838
}, [userData, setUserData]);
3939

40+
// 감정 기록 데이터 불러오기
4041
const {
4142
data: emotionRecords,
4243
isLoading: isEmotionLoading,
@@ -66,53 +67,9 @@ function UserProfile({ isMyPage }: { isMyPage: boolean }) {
6667
setSelectedRecordId(recordId);
6768
openSheet('isCardSheetOpen'); // 모달 열기
6869
};
69-
// 감정 기록 삭제
70-
const { mutate } = useMutation({
71-
mutationFn: (recordId: number) => deleteEmotionRecord(recordId),
72-
onMutate: async (recordId) => {
73-
// 낙관적 업데이트 전에 사용자 목록 쿼리를 취소해 잠재적인 충돌 방지!
74-
await queryClient.cancelQueries({
75-
queryKey: isMyPage
76-
? ['emotionRecords', userData?.data?.loginId]
77-
: ['emotionRecords', userId],
78-
});
79-
// 캐시된 데이터(사용자 목록) 가져오기!
80-
const previousRecords = queryClient.getQueryData<EmotionRecord[]>([
81-
'emotionRecords',
82-
isMyPage ? userData?.data?.loginId : userId,
83-
]);
8470

85-
if (previousRecords) {
86-
queryClient.setQueryData(
87-
['emotionRecords', isMyPage ? userData?.data?.loginId : userId],
88-
(oldData: any) => ({
89-
...oldData,
90-
data: {
91-
...oldData.data,
92-
records: oldData.data.records.filter((r: EmotionRecord) => r.recordId !== recordId),
93-
},
94-
}),
95-
);
96-
}
97-
// 각 콜백의 context로 전달할 데이터 반환!
98-
return { previousRecords };
99-
},
100-
onError: (_, __, context) => {
101-
if (context?.previousRecords) {
102-
queryClient.setQueryData(
103-
['emotionRecords', isMyPage ? userData?.data?.loginId : userId],
104-
context.previousRecords,
105-
);
106-
}
107-
},
108-
onSettled: () => {
109-
queryClient.invalidateQueries({
110-
queryKey: isMyPage
111-
? ['emotionRecords', userData?.data?.loginId]
112-
: ['emotionRecords', userId],
113-
});
114-
},
115-
});
71+
// 감정 기록 삭제
72+
const { mutate } = useDeleteEmotionRecord(isMyPage ? userData?.data?.loginId : userId);
11673

11774
// 삭제모달 띄우기
11875
const handleDeleteModal = () => {

0 commit comments

Comments
 (0)