From 1da22331bbc46da3089394550a0da9a08ccf269e Mon Sep 17 00:00:00 2001 From: Jungu Lee <1zzangjun@gmail.com> Date: Tue, 28 Nov 2023 02:42:57 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Refactor=20:=20=EB=A6=AC=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/GlobalToast.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/src/components/GlobalToast.tsx b/client/src/components/GlobalToast.tsx index 371e31c..2931069 100644 --- a/client/src/components/GlobalToast.tsx +++ b/client/src/components/GlobalToast.tsx @@ -8,7 +8,11 @@ import { CheckCircle, Error, Warning } from "@mui/icons-material"; import { Snackbar, SnackbarContent, Stack } from "@mui/material"; const GlobalToast = () => { - const { isOpen, variant, message, closeToast } = useGlobalSnackbarStore(); + const isOpen = useGlobalSnackbarStore((store) => store.isOpen); + const variant = useGlobalSnackbarStore((store) => store.variant); + const message = useGlobalSnackbarStore((store) => store.message); + const closeToast = useGlobalSnackbarStore((store) => store.closeToast); + return ( { switch (variant) { case "danger": - return ; + return ; case "warning": - return ; + return ; default: - return ; + return ; } }; From 8786f33c781fa412caea5b4e2d7b1c8741474e20 Mon Sep 17 00:00:00 2001 From: Jungu Lee <1zzangjun@gmail.com> Date: Tue, 28 Nov 2023 02:45:04 +0900 Subject: [PATCH 2/5] =?UTF-8?q?New=20:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EC=97=90=EB=9F=AC=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/errorHandler.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/client/src/utils/errorHandler.ts b/client/src/utils/errorHandler.ts index 09a1910..6cddc1b 100644 --- a/client/src/utils/errorHandler.ts +++ b/client/src/utils/errorHandler.ts @@ -1,12 +1,22 @@ "use client"; -// import { useGlobalSnackbarStore } from "@/store/useGlobalSnackbarStore"; +import { useGlobalSnackbarStore } from "@/store/useGlobalSnackbarStore"; import { isAxiosError } from "axios"; +import { useCallback } from "react"; -export default function ErrorHandler(error: Error) { - // const { fireToast } = useGlobalSnackbarStore(); - if (isAxiosError(error) && error.response) { - // FIXME : Zustand 사용 연구 - // error.response.status === 401 && fireToast("로그인 후 이용 가능합니다"); - error.response.status === 401 && console.log("로그인 후 이용 가능합니다"); - } -} +/** + * Axios 에러의 status 코드를 판별해 적절한 토스트팝업을 표출해주는 함수를 리런하는 훅 + * @returns errorHandler (error)=>void + */ +export const useErrorHandler = () => { + const fireToast = useGlobalSnackbarStore((state) => state.fireToast); + + const errorHandler = useCallback((error: Error) => { + if (isAxiosError(error) && error.response) { + switch (error.response.status) { + case 401: + fireToast("로그인 후 이용 가능합니다"); + } + } + }, []); + return errorHandler; +}; From fad8f51694fc7c911f78b16767eaa826f53ca037 Mon Sep 17 00:00:00 2001 From: Jungu Lee <1zzangjun@gmail.com> Date: Tue, 28 Nov 2023 02:45:33 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Minor=20:=20tsx=20->=20ts=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/store/useGlobalLoadingStore.tsx | 11 ----------- client/src/store/useGlobalSnackbarStore.ts | 4 +--- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 client/src/store/useGlobalLoadingStore.tsx diff --git a/client/src/store/useGlobalLoadingStore.tsx b/client/src/store/useGlobalLoadingStore.tsx deleted file mode 100644 index f35bfbf..0000000 --- a/client/src/store/useGlobalLoadingStore.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { create } from "zustand"; - -interface GlobalLoadingStore { - isLoading: boolean; - setLoading: (val: boolean) => void; -} - -export const useGlobalLoadingStore = create((set) => ({ - isLoading: false, - setLoading: (val) => set(() => ({ isLoading: val })), -})); diff --git a/client/src/store/useGlobalSnackbarStore.ts b/client/src/store/useGlobalSnackbarStore.ts index 74efec2..0552956 100644 --- a/client/src/store/useGlobalSnackbarStore.ts +++ b/client/src/store/useGlobalSnackbarStore.ts @@ -16,6 +16,4 @@ export const useGlobalSnackbarStore = create((set) => ({ fireToast: (message, variant = "neutral") => set({ isOpen: true, message, variant }), closeToast: () => set((prev) => ({ ...prev, message: "", isOpen: false })), -})); - -export const useFireToast =()=> useGlobalSnackbarStore((state)=>state.fireToast) +})); \ No newline at end of file From 397cee0aecfd758e687b7ea2bea06e499329af1b Mon Sep 17 00:00:00 2001 From: Jungu Lee <1zzangjun@gmail.com> Date: Tue, 28 Nov 2023 02:45:44 +0900 Subject: [PATCH 4/5] =?UTF-8?q?New=20:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/ErrorPage.tsx | 6 ++++-- client/src/queries/auth/useLoginMutation.tsx | 10 +++++----- client/src/queries/auth/useSignupMutation.tsx | 4 +++- client/src/queries/newPost/useNewPostMutation.tsx | 3 ++- client/src/queries/post/useDeletePostMutation.ts | 9 +++++---- client/src/queries/post/useLikePostMutation.tsx | 7 ++++--- client/src/queries/post/useUnLikePostMutation.tsx | 5 +++-- client/src/queries/user/useFollowMutation.ts | 3 ++- client/src/queries/user/useUnFollowMutation.ts | 4 +++- client/src/store/useGlobalLoadingStore.ts | 11 +++++++++++ 10 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 client/src/store/useGlobalLoadingStore.ts diff --git a/client/src/components/ErrorPage.tsx b/client/src/components/ErrorPage.tsx index 4eb7e3f..10df301 100644 --- a/client/src/components/ErrorPage.tsx +++ b/client/src/components/ErrorPage.tsx @@ -3,7 +3,7 @@ import { Button, Paper } from "@mui/material"; import hasErrorPage from "@/assets/images/hasError.png"; import Image from "next/image"; import { useEffect } from "react"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; const ErrorPage = ({ error, @@ -12,6 +12,8 @@ const ErrorPage = ({ error: Error & { digest?: string }; reset: () => void; }) => { + const errorHandler = useErrorHandler(); + useEffect(() => { errorHandler(error); }, [error]); @@ -24,7 +26,7 @@ const ErrorPage = ({ flexDirection: "column", alignItems: "center", height: "calc(100vh - 56px)", - gap:2 + gap: 2, }} > 에러임을 알림 diff --git a/client/src/queries/auth/useLoginMutation.tsx b/client/src/queries/auth/useLoginMutation.tsx index 74ba379..2e0ac5a 100644 --- a/client/src/queries/auth/useLoginMutation.tsx +++ b/client/src/queries/auth/useLoginMutation.tsx @@ -5,8 +5,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { MyInfoQueryKeys } from "./useMyInfoQuery"; import { useRouter } from "next/navigation"; import HOME from "@/const/clientPath"; -import errorHandler from "@/utils/errorHandler"; -import { AxiosError } from "axios"; +import { useErrorHandler } from "@/utils/errorHandler"; import { useGlobalLoadingStore } from "@/store/useGlobalLoadingStore"; const useLoginMutation = () => { @@ -14,6 +13,7 @@ const useLoginMutation = () => { const queryClient = useQueryClient(); const router = useRouter(); const { setLoading } = useGlobalLoadingStore(); + const errorHandler = useErrorHandler(); return useMutation({ mutationKey: LoginMuataionKey.all, @@ -29,8 +29,7 @@ const useLoginMutation = () => { router.refresh(); router.push(HOME); }, - onError: (error) => - errorHandler(error), + onError: (error) => errorHandler(error), onSettled: () => { setLoading(false); }, @@ -52,6 +51,7 @@ export const LoginMuataionKey = { * @param id 유저아이디 * @returns 로그인뮤테이션 키 */ - byId: (id: SigninRequirement["id"]) => [...LoginMuataionKey.all, {id}] as const, + byId: (id: SigninRequirement["id"]) => + [...LoginMuataionKey.all, { id }] as const, }; export default useLoginMutation; diff --git a/client/src/queries/auth/useSignupMutation.tsx b/client/src/queries/auth/useSignupMutation.tsx index 509c721..c3dd030 100644 --- a/client/src/queries/auth/useSignupMutation.tsx +++ b/client/src/queries/auth/useSignupMutation.tsx @@ -5,11 +5,13 @@ import { SignupRequirement } from "@/types/auth/signupRequirement"; import { useMutation } from "@tanstack/react-query"; import useLoginMutation from "./useLoginMutation"; import { useGlobalLoadingStore } from "@/store/useGlobalLoadingStore"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; const useSignupMutation = () => { const { mutate: loginHandler } = useLoginMutation(); const { setLoading } = useGlobalLoadingStore(); + const errorHandler = useErrorHandler(); + return useMutation({ mutationKey: signupMuataionKey.all, mutationFn: async (formData: SignupRequirement) => { diff --git a/client/src/queries/newPost/useNewPostMutation.tsx b/client/src/queries/newPost/useNewPostMutation.tsx index 494fd88..12d066f 100644 --- a/client/src/queries/newPost/useNewPostMutation.tsx +++ b/client/src/queries/newPost/useNewPostMutation.tsx @@ -3,9 +3,10 @@ import axios from "@/libs/axios"; import { POST_LIST } from "@/const/serverPath"; import { NewPostRequestInterface } from "@/types/newPost/NewPostInterface"; import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; const useNewPostMutation = () => { + const errorHandler = useErrorHandler(); return useMutation({ mutationFn: async (formData: NewPostRequestInterface) => { const data = await usePostNewPostFn(formData); diff --git a/client/src/queries/post/useDeletePostMutation.ts b/client/src/queries/post/useDeletePostMutation.ts index 481767b..2a6cad0 100644 --- a/client/src/queries/post/useDeletePostMutation.ts +++ b/client/src/queries/post/useDeletePostMutation.ts @@ -2,18 +2,19 @@ import { REMOVE_POST } from "@/const/serverPath"; import { axiosPrivate } from "@/libs/axios"; import { useMutation } from "@tanstack/react-query"; import { useInvalidatePostList } from "./useGetPostListInfiniteQuery"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; export const useDeletePostMutation = () => { const invalidatePreviousData = useInvalidatePostList(); + const errorHandler = useErrorHandler(); return useMutation({ mutationFn: (pk: number) => deletePostFn(pk), onSuccess: () => { invalidatePreviousData(); }, - onError:(err)=>{ - errorHandler(err) - } + onError: (err) => { + errorHandler(err); + }, }); }; diff --git a/client/src/queries/post/useLikePostMutation.tsx b/client/src/queries/post/useLikePostMutation.tsx index 09d6ede..f39908d 100644 --- a/client/src/queries/post/useLikePostMutation.tsx +++ b/client/src/queries/post/useLikePostMutation.tsx @@ -12,7 +12,7 @@ import { } from "./useGetPostListInfiniteQuery"; import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage"; import { POST_LIKE_URL } from "@/const/serverPath"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; import { PostcardContextInterface } from "@/store/PostCardContext"; import { useOptimisticUpdatePostList } from "@/queries/post/updator/useOptimisticUpdatePostList"; import { useOptimisticUpdatePostDetail } from "./updator/useOptimisticUpdatePostDetail"; @@ -26,7 +26,8 @@ import { postDetailQueryKey } from "./useGetPostDetailQuery"; */ const useLikePostMutation = (context?: PostcardContextInterface) => { const queryClient = useQueryClient(); - + + const errorHandler = useErrorHandler(); const postListUpdator = useOptimisticUpdatePostList({ type: "like" }); const postDetailUpdator = useOptimisticUpdatePostDetail({ type: "like" }); @@ -52,7 +53,7 @@ const useLikePostMutation = (context?: PostcardContextInterface) => { ); // [디테일쿼리] const detailQuerySnapshot = queryClient.getQueryData( - postDetailQueryKey.byId(String(id)), + postDetailQueryKey.byId(String(id)) ); // Optimastic Update // [리스트 쿼리] diff --git a/client/src/queries/post/useUnLikePostMutation.tsx b/client/src/queries/post/useUnLikePostMutation.tsx index ba19ac1..7a46171 100644 --- a/client/src/queries/post/useUnLikePostMutation.tsx +++ b/client/src/queries/post/useUnLikePostMutation.tsx @@ -12,7 +12,7 @@ import { } from "./useGetPostListInfiniteQuery"; import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage"; import { POST_UN_LIKE_URL } from "@/const/serverPath"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; import { PostcardContextInterface } from "@/store/PostCardContext"; import { useOptimisticUpdatePostList } from "@/queries/post/updator/useOptimisticUpdatePostList"; import { useOptimisticUpdatePostDetail } from "./updator/useOptimisticUpdatePostDetail"; @@ -26,6 +26,7 @@ import { postDetailQueryKey } from "./useGetPostDetailQuery"; */ const useLikePostMutation = (context?: PostcardContextInterface) => { const queryClient = useQueryClient(); + const errorHandler = useErrorHandler(); const postListUpdator = useOptimisticUpdatePostList({ type: "unlike" }); const postDetailUpdator = useOptimisticUpdatePostDetail({ type: "unlike" }); @@ -53,7 +54,7 @@ const useLikePostMutation = (context?: PostcardContextInterface) => { ); // [디테일쿼리] const detailQuerySnapshot = queryClient.getQueryData( - postDetailQueryKey.byId(String(id)), + postDetailQueryKey.byId(String(id)) ); // Optimastic Update diff --git a/client/src/queries/user/useFollowMutation.ts b/client/src/queries/user/useFollowMutation.ts index 824eb49..027a006 100644 --- a/client/src/queries/user/useFollowMutation.ts +++ b/client/src/queries/user/useFollowMutation.ts @@ -6,10 +6,11 @@ import { UserInfoQueryKey } from "./useUserInfoQuery"; import { UserInfoInterface } from "@/types/user/userInfoInterface"; import { MyInfoQueryKeys } from "../auth/useMyInfoQuery"; import { MyInfoInterface } from "@/types/auth/myInfo"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; const useFollowMutation = () => { const queryClient = useQueryClient(); + const errorHandler = useErrorHandler(); return useMutation({ mutationFn: async (userNo: string) => await followUserMutatuibFn(userNo), /** diff --git a/client/src/queries/user/useUnFollowMutation.ts b/client/src/queries/user/useUnFollowMutation.ts index 4fc9b28..36cdc89 100644 --- a/client/src/queries/user/useUnFollowMutation.ts +++ b/client/src/queries/user/useUnFollowMutation.ts @@ -6,10 +6,12 @@ import { UserInfoQueryKey } from "./useUserInfoQuery"; import { UserInfoInterface } from "@/types/user/userInfoInterface"; import { MyInfoQueryKeys } from "../auth/useMyInfoQuery"; import { MyInfoInterface } from "@/types/auth/myInfo"; -import errorHandler from "@/utils/errorHandler"; +import { useErrorHandler } from "@/utils/errorHandler"; const useUnFollowMutation = () => { const queryClient = useQueryClient(); + const errorHandler = useErrorHandler(); + return useMutation({ mutationFn: async (userNo: string) => await followUserMutationFn(userNo), /** diff --git a/client/src/store/useGlobalLoadingStore.ts b/client/src/store/useGlobalLoadingStore.ts new file mode 100644 index 0000000..f35bfbf --- /dev/null +++ b/client/src/store/useGlobalLoadingStore.ts @@ -0,0 +1,11 @@ +import { create } from "zustand"; + +interface GlobalLoadingStore { + isLoading: boolean; + setLoading: (val: boolean) => void; +} + +export const useGlobalLoadingStore = create((set) => ({ + isLoading: false, + setLoading: (val) => set(() => ({ isLoading: val })), +})); From a2b03e494308bc7b3d2f8d4a83db42871acb9a2c Mon Sep 17 00:00:00 2001 From: Jungu Lee <1zzangjun@gmail.com> Date: Tue, 28 Nov 2023 03:01:43 +0900 Subject: [PATCH 5/5] =?UTF-8?q?New=20:=20=ED=86=A0=ED=81=B0=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/errorHandler.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/utils/errorHandler.ts b/client/src/utils/errorHandler.ts index 6cddc1b..e4c069a 100644 --- a/client/src/utils/errorHandler.ts +++ b/client/src/utils/errorHandler.ts @@ -15,6 +15,8 @@ export const useErrorHandler = () => { switch (error.response.status) { case 401: fireToast("로그인 후 이용 가능합니다"); + // 토큰이 만료된 경우가 대부분이므로 토큰제거 + localStorage.removeItem('accessToken') } } }, []);