1- import { useState } from 'react'
21import { useNavigate } from 'react-router-dom'
32
43import { useMutation , useQuery , useQueryClient } from '@tanstack/react-query'
54
65import { useAuthStore } from '@/features/auth/store/authStore'
76import { postLike , deleteLike , getLikeStatus } from '@/features/like/api/like'
7+ import type { LikeStatusResponse } from '@/features/like/type/like'
88
9- const useLike = ( playlistId : number , initialIsLiked : boolean ) => {
9+ export const useLikeStatus = ( playlistId : number , options ?: { enabled ?: boolean } ) => {
10+ return useQuery ( {
11+ queryKey : [ 'likeStatus' , playlistId ] ,
12+ queryFn : ( ) => getLikeStatus ( playlistId ) ,
13+ staleTime : 0 ,
14+ enabled : playlistId !== undefined && ( options ?. enabled ?? true ) ,
15+ } )
16+ }
17+
18+ const useLike = ( playlistId : number ) => {
1019 const queryClient = useQueryClient ( )
11- const [ isLiked , setIsLiked ] = useState ( initialIsLiked )
12- const navigate = useNavigate ( )
1320 const { isLogin } = useAuthStore ( )
21+ const navigate = useNavigate ( )
22+
23+ const { data : statusData , isLoading } = useLikeStatus ( playlistId , { enabled : isLogin } )
24+ const isLiked = statusData ?. isLiked ?? false
1425
1526 const likeMutation = useMutation ( {
16- mutationFn : ( playlistId : number ) => postLike ( playlistId ) ,
17- onSuccess : ( ) => {
18- setIsLiked ( true )
19- queryClient . invalidateQueries ( { queryKey : [ 'playlistDetail' , playlistId ] } )
27+ mutationFn : ( ) => postLike ( playlistId ) ,
28+
29+ onMutate : async ( ) => {
30+ await queryClient . cancelQueries ( { queryKey : [ 'likeStatus' , playlistId ] } )
31+ const previous = queryClient . getQueryData ( [ 'likeStatus' , playlistId ] )
32+
33+ // λκ΄μ μ
λ°μ΄νΈ
34+ queryClient . setQueryData < LikeStatusResponse > ( [ 'likeStatus' , playlistId ] , ( old ) => ( {
35+ ...( old ?? { isLiked : false } ) ,
36+ isLiked : true ,
37+ } ) )
38+
39+ return { previous }
40+ } ,
41+ onError : ( _err , _vars , context ) => {
42+ // contextλ onMutateμ return κ°(previous)
43+ if ( context ?. previous ) {
44+ // μ€ν¨ μ UIλ₯Ό μλλλ‘ λλ¦Ό
45+ queryClient . setQueryData ( [ 'likeStatus' , playlistId ] , context . previous )
46+ }
47+ } ,
48+
49+ // μ±κ³΅ μ€ν¨ κ΄κ³ μμ΄ λ¬΄μ‘°κ±΄ μ€ν
50+ onSettled : ( ) => {
51+ queryClient . invalidateQueries ( { queryKey : [ 'likeStatus' , playlistId ] } )
2052 } ,
2153 } )
2254
2355 const unlikeMutation = useMutation ( {
24- mutationFn : ( playlistId : number ) => deleteLike ( playlistId ) ,
25- onSuccess : ( ) => {
26- setIsLiked ( false )
27- queryClient . invalidateQueries ( { queryKey : [ 'playlistDetail' , playlistId ] } )
56+ mutationFn : ( ) => deleteLike ( playlistId ) ,
57+
58+ onMutate : async ( ) => {
59+ await queryClient . cancelQueries ( { queryKey : [ 'likeStatus' , playlistId ] } )
60+ const previous = queryClient . getQueryData ( [ 'likeStatus' , playlistId ] )
61+
62+ queryClient . setQueryData < LikeStatusResponse > ( [ 'likeStatus' , playlistId ] , ( old ) => ( {
63+ ...( old ?? { isLiked : false } ) ,
64+ isLiked : true ,
65+ } ) )
66+
67+ return { previous }
68+ } ,
69+
70+ onError : ( _err , _vars , context ) => {
71+ if ( context ?. previous ) {
72+ queryClient . setQueryData ( [ 'likeStatus' , playlistId ] , context . previous )
73+ }
74+ } ,
75+
76+ onSettled : ( ) => {
77+ queryClient . invalidateQueries ( { queryKey : [ 'likeStatus' , playlistId ] } )
2878 } ,
2979 } )
3080
@@ -34,25 +84,11 @@ const useLike = (playlistId: number, initialIsLiked: boolean) => {
3484 return
3585 }
3686
37- if ( likeMutation . isPending || unlikeMutation . isPending ) return
38-
39- if ( isLiked ) {
40- unlikeMutation . mutate ( playlistId )
41- } else {
42- likeMutation . mutate ( playlistId )
43- }
87+ if ( isLiked ) unlikeMutation . mutate ( )
88+ else likeMutation . mutate ( )
4489 }
4590
46- return { liked : isLiked , toggleLike, likeMutation , unlikeMutation }
91+ return { liked : isLiked , toggleLike, isLoading }
4792}
4893
4994export default useLike
50-
51- export const useLikeStatus = ( playlistId : number , options ?: { enabled ?: boolean } ) => {
52- return useQuery ( {
53- queryKey : [ 'likeStatus' , playlistId ] ,
54- queryFn : ( ) => getLikeStatus ( playlistId ) ,
55- staleTime : 0 ,
56- enabled : playlistId !== undefined && ( options ?. enabled ?? true ) ,
57- } )
58- }
0 commit comments