diff --git a/src/apis/emotion/emotion.queries.ts b/src/apis/emotion/emotion.queries.ts index 35fa958..21ebb66 100644 --- a/src/apis/emotion/emotion.queries.ts +++ b/src/apis/emotion/emotion.queries.ts @@ -7,11 +7,12 @@ import { createEmotionLogToday, getEmotionLogsMonthly, } from './emotion.service'; +import { EmotionLog } from './emotion.type'; export const useEmotionLogToday = (userId: number | null) => { return useQuery({ queryKey: ['emotion', 'today', userId], - queryFn: () => (userId ? getEmotionLogToday({ userId }) : Promise.resolve(null)), + queryFn: () => getEmotionLogToday({ userId: userId! }), enabled: userId !== null, retryOnMount: false, }); @@ -21,11 +22,29 @@ export const useCreateEmotionLog = (userId: number | null) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: (data: { emotion: Emotion }) => createEmotionLogToday(data), - onSuccess: () => { - if (userId !== null) { - queryClient.invalidateQueries({ queryKey: ['emotion'] }); + onMutate: async (data: { emotion: Emotion }) => { + if (userId === null) return; + + await queryClient.cancelQueries({ queryKey: ['emotion', 'today', userId] }); + const previousData = queryClient.getQueryData(['emotion', 'today', userId]); + + if (previousData) { + queryClient.setQueryData(['emotion', 'today', userId], { + ...previousData, + emotion: data.emotion, + }); + } + + return { previousData }; + }, + onError: (_, __, context) => { + if (context?.previousData) { + queryClient.setQueryData(['emotion', 'today', userId], context.previousData); } }, + onSuccess: async () => { + queryClient.invalidateQueries({ queryKey: ['emotion'] }); + }, }); }; diff --git a/src/app/(after-login)/epigrams/_components/TodayEmotion.tsx b/src/app/(after-login)/epigrams/_components/TodayEmotion.tsx index 9c2151f..ad53e34 100644 --- a/src/app/(after-login)/epigrams/_components/TodayEmotion.tsx +++ b/src/app/(after-login)/epigrams/_components/TodayEmotion.tsx @@ -16,7 +16,6 @@ export default function TodayEmotion() { const handleEmotionClick = (emotion: Emotion) => { if (isPending) return; - createEmotion({ emotion }); }; @@ -33,6 +32,7 @@ export default function TodayEmotion() { emotion={emotion} onEmotionClick={handleEmotionClick} label='오늘의 감정을 선택해 주세요' + isLoading={isPending} /> )} diff --git a/src/app/(after-login)/mypage/_components/MyEmotions.tsx b/src/app/(after-login)/mypage/_components/MyEmotions.tsx index 3dd30d8..ae50528 100644 --- a/src/app/(after-login)/mypage/_components/MyEmotions.tsx +++ b/src/app/(after-login)/mypage/_components/MyEmotions.tsx @@ -20,7 +20,6 @@ export default function MyEmotions() { const handleEmotionClick = (emotion: Emotion) => { if (isPending) return; - createEmotion({ emotion }); }; @@ -31,6 +30,7 @@ export default function MyEmotions() { onEmotionClick={handleEmotionClick} label='오늘의 감정' showDate + isLoading={isPending} /> void; + onEmotionClick: (emotion: Emotion) => void | Promise; + isLoading?: boolean; } export default function TodayMood({ @@ -22,6 +23,7 @@ export default function TodayMood({ showDate = false, emotion, onEmotionClick, + isLoading = false, }: TodayMoodProps) { const selectedEmotion = emotion?.emotion || null; const today = format(new Date(), 'yyyy.MM.dd'); @@ -34,20 +36,22 @@ export default function TodayMood({ {showDate && {today}} -
- {Object.values(EMOTION).map((emotion) => ( - onEmotionClick(emotion)} - selected={selectedEmotion === emotion} - /> - ))} +
+
+ {Object.values(EMOTION).map((emotion) => ( + onEmotionClick(emotion)} + selected={selectedEmotion === emotion} + /> + ))} +
);