From 660aab9e4c46222b5f763b631cf61df160d2d8a4 Mon Sep 17 00:00:00 2001 From: TaeeunKim Date: Thu, 2 Nov 2023 20:45:06 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=BF=80=EC=A1=B0=ED=95=A9=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=EB=8A=94=20server=20state=EB=A5=BC=20?= =?UTF-8?q?=EB=8F=99=EA=B8=B0=ED=99=94=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecipeFavoriteButton.tsx | 29 +++---------------- .../recipe/useRecipeFavoriteMutation.ts | 25 ++++++++++++++-- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx b/frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx index b4cab603..4685676c 100644 --- a/frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx +++ b/frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx @@ -1,5 +1,4 @@ import { theme, Button, Text } from '@fun-eat/design-system'; -import { useState } from 'react'; import styled from 'styled-components'; import { SvgIcon } from '@/components/Common'; @@ -13,30 +12,10 @@ interface RecipeFavoriteProps { } const RecipeFavoriteButton = ({ recipeId, favorite, favoriteCount }: RecipeFavoriteProps) => { - const initialFavoriteState = { - isFavorite: favorite, - currentFavoriteCount: favoriteCount, - }; - - const [favoriteInfo, setFavoriteInfo] = useState(initialFavoriteState); - const { mutate } = useRecipeFavoriteMutation(Number(recipeId)); - const { isFavorite, currentFavoriteCount } = favoriteInfo; const handleToggleFavorite = async () => { - setFavoriteInfo((prev) => ({ - isFavorite: !prev.isFavorite, - currentFavoriteCount: isFavorite ? prev.currentFavoriteCount - 1 : prev.currentFavoriteCount + 1, - })); - - mutate( - { favorite: !isFavorite }, - { - onError: () => { - setFavoriteInfo(initialFavoriteState); - }, - } - ); + mutate({ favorite: !favorite }); }; const [debouncedToggleFavorite] = useTimeout(handleToggleFavorite, 200); @@ -44,12 +23,12 @@ const RecipeFavoriteButton = ({ recipeId, favorite, favoriteCount }: RecipeFavor return ( - {currentFavoriteCount} + {favoriteCount} ); diff --git a/frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts b/frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts index 3e736d88..33e7c3f8 100644 --- a/frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts +++ b/frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { recipeApi } from '@/apis'; import { useToastActionContext } from '@/hooks/context'; -import type { RecipeFavoriteRequestBody } from '@/types/recipe'; +import type { RecipeFavoriteRequestBody, RecipeDetail } from '@/types/recipe'; const headers = { 'Content-Type': 'application/json' }; @@ -18,7 +18,24 @@ const useRecipeFavoriteMutation = (recipeId: number) => { return useMutation({ mutationFn: (body: RecipeFavoriteRequestBody) => patchRecipeFavorite(recipeId, body), - onError: (error) => { + onMutate: async (newFavoriteRequest) => { + await queryClient.cancelQueries({ queryKey: queryKey }); + + const previousRequest = queryClient.getQueryData(queryKey); + console.log(previousRequest); + + if (previousRequest) { + queryClient.setQueryData(queryKey, () => ({ + ...previousRequest, + newFavoriteRequest, + })); + } + + return { previousRequest }; + }, + onError: (error, _, context) => { + queryClient.setQueryData(queryKey, context?.previousRequest); + if (error instanceof Error) { toast.error(error.message); return; @@ -26,7 +43,9 @@ const useRecipeFavoriteMutation = (recipeId: number) => { toast.error('꿀조합 좋아요를 다시 시도해주세요.'); }, - onSuccess: () => queryClient.invalidateQueries({ queryKey: queryKey }), + onSettled: () => { + queryClient.invalidateQueries({ queryKey: queryKey }); + }, }); };