From 10a603e4877fce5f8bc5ff87e816b50e8391b589 Mon Sep 17 00:00:00 2001 From: un0211 Date: Wed, 10 Jul 2024 16:25:45 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20refactor(#237):=20q?= =?UTF-8?q?ueryCache=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Redirect/index.tsx | 69 ++++++++++++++------- src/containers/dashboard/ColumnsSection.tsx | 34 +++------- src/containers/dashboard/edit/index.tsx | 24 +------ src/hooks/useDeleteData.ts | 7 ++- src/hooks/useFetchData.ts | 3 +- src/hooks/useRedirect.ts | 25 ++++++++ src/hooks/useRedirectIfAuth.ts | 30 --------- src/hooks/useRedirectIfNoPermission.ts | 33 ---------- src/hooks/useRedirectIfNotAuth.ts | 30 --------- src/hooks/useRedirectIfNotMember.ts | 30 --------- src/pages/_app.tsx | 23 +++---- 11 files changed, 96 insertions(+), 212 deletions(-) create mode 100644 src/hooks/useRedirect.ts delete mode 100644 src/hooks/useRedirectIfAuth.ts delete mode 100644 src/hooks/useRedirectIfNoPermission.ts delete mode 100644 src/hooks/useRedirectIfNotAuth.ts delete mode 100644 src/hooks/useRedirectIfNotMember.ts diff --git a/src/components/Redirect/index.tsx b/src/components/Redirect/index.tsx index 61c1c7e8..7e6f01f4 100644 --- a/src/components/Redirect/index.tsx +++ b/src/components/Redirect/index.tsx @@ -1,40 +1,63 @@ +import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { AxiosError } from 'axios'; import { useRouter } from 'next/router'; +import { useEffect } from 'react'; import { useSelector } from 'react-redux'; -import useRedirectIfAuth from '@/hooks/useRedirectIfAuth'; -import useRedirectIfNotAuth from '@/hooks/useRedirectIfNotAuth'; +import useRedirect from '@/hooks/useRedirect'; import { RootState } from '@/store/store'; export default function Redirect({ children }: { children: React.ReactNode }) { + const redirect = useRedirect(); const router = useRouter(); const { user } = useSelector((state: RootState) => state.user); const currentPath = router.pathname; - const redirectIfAuth = useRedirectIfAuth(); - const redirectIfNotAuth = useRedirectIfNotAuth(); - - if (currentPath === '/' && user) { - router.replace('/mydashboard'); - } + // NOTE: QueryCache로 글로벌 콜백 설정 + const queryCache = new QueryCache({ + onError: (error) => { + if (error instanceof AxiosError) { + switch (error.response?.status) { + case 401: + redirect('/signin', '로그인이 필요합니다'); + break; + case 403: + case 404: + if (user) redirect('/mydashboard', '접근 권한이 없습니다'); + else redirect('/signin', '접근 권한이 없습니다'); + } + } + }, + }); + + const queryClient = new QueryClient({ + queryCache, + defaultOptions: { + queries: { + retry: 0, + refetchOnWindowFocus: false, + }, + }, + }); + + useEffect(() => { + if (currentPath === '/' && user) { + router.replace('/mydashboard'); + } - if (currentPath === '/404') { - const nextPath = user ? '/mydashboard' : '/'; - setTimeout(() => router.push(nextPath), 3000); - } + if (currentPath === '/404') { + const nextPath = user ? '/mydashboard' : '/'; + setTimeout(() => router.push(nextPath), 3000); + } - if (['/signup', '/signin'].includes(currentPath)) { - const isRedirecting = redirectIfAuth(); - if (isRedirecting) { - return <>; + if (['/signup', '/signin'].includes(currentPath) && user) { + redirect('/mydashboard', '이미 로그인했습니다'); } - } - if (['/mypage', '/mydashboard'].includes(currentPath)) { - const isRedirecting = redirectIfNotAuth(); - if (isRedirecting) { - return <>; + if (['/mypage', '/mydashboard'].includes(currentPath) && !user) { + redirect('/signin', '로그인이 필요합니다'); } - } + }, [currentPath, router.query.id]); - return children; + return {children}; } diff --git a/src/containers/dashboard/ColumnsSection.tsx b/src/containers/dashboard/ColumnsSection.tsx index 53d0606d..73089938 100644 --- a/src/containers/dashboard/ColumnsSection.tsx +++ b/src/containers/dashboard/ColumnsSection.tsx @@ -8,13 +8,11 @@ import Column from './Column'; import useFetchData from '@/hooks/useFetchData'; import useModal from '@/hooks/useModal'; -import useRedirectIfNotMember from '@/hooks/useRedirectIfNotMember'; import instance from '@/services/axios'; -import { getColumnsList, getDashboard } from '@/services/getService'; +import { getColumnsList } from '@/services/getService'; import { moveToOtherColumn } from '@/services/putService'; import { RootState } from '@/store/store'; import { ColumnsResponse } from '@/types/Column.interface'; -import { checkPublic } from '@/utils/shareAccount'; interface ColumnsSectionProps { dashboardId: string; @@ -23,10 +21,8 @@ interface ColumnsSectionProps { export default function ColumnsSection({ dashboardId }: ColumnsSectionProps) { const queryClient = useQueryClient(); const { openNewColumnModal, openNotificationModal } = useModal(); - const redirectIfNotMember = useRedirectIfNotMember(); const { user } = useSelector((state: RootState) => state.user); const [isMember, setIsMember] = useState(true); - const [isPublic, setIsPublic] = useState(false); const { data: columns, @@ -37,31 +33,17 @@ export default function ColumnsSection({ dashboardId }: ColumnsSectionProps) { const columnList = columns?.data || []; useEffect(() => { - const handleRedirect = async () => { + const handleCheckMember = async () => { + if (!dashboardId) return; try { - const newIsPublic = await checkPublic(Number(dashboardId)); - setIsPublic(newIsPublic); - if (!newIsPublic && dashboardId) { - await getDashboard(String(dashboardId)); - } + await instance.get(`/dashboards/${dashboardId}`, { + headers: { memberTest: true }, + }); } catch { - redirectIfNotMember(); - } - }; - - const handleCheckMember = async () => { - if (dashboardId) { - try { - await instance.get(`/dashboards/${dashboardId}`, { - headers: { memberTest: true }, - }); - } catch { - setIsMember(false); - } + setIsMember(false); } }; - handleRedirect(); handleCheckMember(); }, [dashboardId, user]); @@ -106,7 +88,7 @@ export default function ColumnsSection({ dashboardId }: ColumnsSectionProps) { ) : (
    {columnList.map((column, index) => ( diff --git a/src/containers/dashboard/edit/index.tsx b/src/containers/dashboard/edit/index.tsx index 28594e14..a4ec4153 100644 --- a/src/containers/dashboard/edit/index.tsx +++ b/src/containers/dashboard/edit/index.tsx @@ -9,23 +9,17 @@ import InvitedMembersSection from './InvitedMembersSection'; import MembersSection from './MembersSection'; import useDeleteData from '@/hooks/useDeleteData'; -import useFetchData from '@/hooks/useFetchData'; import useModal from '@/hooks/useModal'; -import useRedirectIfNoPermission from '@/hooks/useRedirectIfNoPermission'; import { deleteDashboard } from '@/services/deleteService'; -import { getDashboard } from '@/services/getService'; -import { Dashboard } from '@/types/Dashboard.interface'; import { DeleteDashboardInput } from '@/types/delete/DeleteDashboardInput.interface'; import { checkPublic } from '@/utils/shareAccount'; export default function DashboardEdit() { - const redirectIfNoPermission = useRedirectIfNoPermission(); const { openConfirmModal } = useModal(); const queryClient = useQueryClient(); const router = useRouter(); const { id } = router.query; - const { data: dashboard, error } = useFetchData(['dashboard', id], () => getDashboard(id as string)); const [isPublic, setIsPublic] = useState(false); const handleSuccess = () => { @@ -58,26 +52,12 @@ export default function DashboardEdit() { useEffect(() => { const handleInitIsPublic = async () => { - try { - setIsPublic(await checkPublic(Number(id))); - } catch { - redirectIfNoPermission(-1); - } + setIsPublic(await checkPublic(Number(id))); }; - if (id) { - handleInitIsPublic(); - } + if (id) handleInitIsPublic(); }, [id]); - useEffect(() => { - if (dashboard) { - redirectIfNoPermission(dashboard.userId); - } else if (error) { - redirectIfNoPermission(-1); - } - }, [dashboard, error]); - return (
    { mutationFn: MutationFunction; handleSuccess?: () => void; @@ -8,6 +10,7 @@ interface UseDeleteProps { } const useDeleteData = ({ mutationFn, handleSuccess, handleError }: UseDeleteProps) => { + const { openNotificationModal } = useModal(); return useMutation({ mutationFn, onSuccess: () => { @@ -23,9 +26,9 @@ const useDeleteData = ({ mutationFn, handleSuccess, handleError }: UseDeleteP } else { // NOTE: 에러 처리는 일관되게 서버 메세지 있는 경우 보여주고, 아니면 로그 출력하도록 했습니다. if (error instanceof AxiosError) { - alert(error.response?.data.message); + openNotificationModal({ text: error.response?.data.message }); } else { - alert('실패했습니다.'); + openNotificationModal({ text: '실패했습니다.' }); console.log(error); } } diff --git a/src/hooks/useFetchData.ts b/src/hooks/useFetchData.ts index 8e9c8b7e..58b03edf 100644 --- a/src/hooks/useFetchData.ts +++ b/src/hooks/useFetchData.ts @@ -15,10 +15,9 @@ const useFetchData = ( handleSuccess && handleSuccess(); return response.data; } catch (error) { - throw new Error('데이터를 불러오는 중 에러 발생: ' + error); + throw error; } }, - retry: 1, refetchInterval: refetchInterval, enabled: enabled, }); diff --git a/src/hooks/useRedirect.ts b/src/hooks/useRedirect.ts new file mode 100644 index 00000000..6dfb2228 --- /dev/null +++ b/src/hooks/useRedirect.ts @@ -0,0 +1,25 @@ +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; + +import useModal from '@/hooks/useModal'; + +const useRedirect = () => { + const { openNotificationModal } = useModal(); + const router = useRouter(); + const { id } = router.query; + const [initialCheck, setInitialCheck] = useState(true); + + useEffect(() => { + setInitialCheck(true); + }, [router.pathname, id]); + + return (path: string, text: string) => { + if (initialCheck) { + openNotificationModal({ text }); + router.replace(path); + setInitialCheck(false); + } + }; +}; + +export default useRedirect; diff --git a/src/hooks/useRedirectIfAuth.ts b/src/hooks/useRedirectIfAuth.ts deleted file mode 100644 index b8ae5ffe..00000000 --- a/src/hooks/useRedirectIfAuth.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useRouter } from 'next/router'; -import { useState } from 'react'; -import { useSelector } from 'react-redux'; - -import useModal from '@/hooks/useModal'; -import { RootState } from '@/store/store'; - -const useRedirectIfAuth = () => { - const { user } = useSelector((state: RootState) => state.user); - const { openNotificationModal } = useModal(); - const router = useRouter(); - const [isRedirecting, setIsRedirecting] = useState(false); - const [initialCheck, setInitialCheck] = useState(true); - - return () => { - if (initialCheck) { - if (user) { - openNotificationModal({ text: '이미 로그인하셨습니다.' }); - setIsRedirecting(true); - router.replace('/mydashboard'); - } - setIsRedirecting(false); - setInitialCheck(false); - } - - return isRedirecting; - }; -}; - -export default useRedirectIfAuth; diff --git a/src/hooks/useRedirectIfNoPermission.ts b/src/hooks/useRedirectIfNoPermission.ts deleted file mode 100644 index d7df9879..00000000 --- a/src/hooks/useRedirectIfNoPermission.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { useRouter } from 'next/router'; -import { useState } from 'react'; -import { useSelector } from 'react-redux'; - -import useModal from '@/hooks/useModal'; -import { RootState } from '@/store/store'; - -const useRedirectIfNoPermission = () => { - const { user } = useSelector((state: RootState) => state.user); - const { openNotificationModal } = useModal(); - const router = useRouter(); - const [isRedirecting, setIsRedirecting] = useState(false); - const [initialCheck, setInitialCheck] = useState(true); - - return (creatorId: number) => { - if (initialCheck) { - if (creatorId !== user?.id) { - openNotificationModal({ text: '접근 권한이 없습니다.' }); - setIsRedirecting(true); - if (user) { - router.replace('/mydashboard'); - } else { - router.replace('/signin'); - } - } - setIsRedirecting(false); - setInitialCheck(false); - } - return isRedirecting; - }; -}; - -export default useRedirectIfNoPermission; diff --git a/src/hooks/useRedirectIfNotAuth.ts b/src/hooks/useRedirectIfNotAuth.ts deleted file mode 100644 index bef73e1e..00000000 --- a/src/hooks/useRedirectIfNotAuth.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useRouter } from 'next/router'; -import { useState } from 'react'; -import { useSelector } from 'react-redux'; - -import useModal from '@/hooks/useModal'; -import { RootState } from '@/store/store'; - -const useRedirectIfNotAuth = () => { - const { user } = useSelector((state: RootState) => state.user); - const { openNotificationModal } = useModal(); - const router = useRouter(); - const [isRedirecting, setIsRedirecting] = useState(false); - const [initialCheck, setInitialCheck] = useState(true); - - return () => { - if (initialCheck) { - if (!user) { - openNotificationModal({ text: '로그인이 필요합니다.' }); - setIsRedirecting(true); - router.replace('/signin'); - } - setIsRedirecting(false); - setInitialCheck(false); - } - - return isRedirecting; - }; -}; - -export default useRedirectIfNotAuth; diff --git a/src/hooks/useRedirectIfNotMember.ts b/src/hooks/useRedirectIfNotMember.ts deleted file mode 100644 index 5d7da60c..00000000 --- a/src/hooks/useRedirectIfNotMember.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useRouter } from 'next/router'; -import { useState } from 'react'; -import { useSelector } from 'react-redux'; - -import useModal from '@/hooks/useModal'; -import { RootState } from '@/store/store'; - -const useRedirectIfNotMember = () => { - const { user } = useSelector((state: RootState) => state.user); - const { openNotificationModal } = useModal(); - const router = useRouter(); - const [isRedirecting, setIsRedirecting] = useState(false); - const [initialCheck, setInitialCheck] = useState(true); - - return () => { - if (initialCheck) { - openNotificationModal({ text: '접근 권한이 없습니다.' }); - setIsRedirecting(true); - if (user) { - router.replace('/mydashboard'); - } else { - router.replace('/signin'); - } - setInitialCheck(false); - } - return isRedirecting; - }; -}; - -export default useRedirectIfNotMember; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index ea463dec..218d3ac5 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,5 +1,4 @@ import '@/styles/globals.css'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import type { AppProps } from 'next/app'; import Head from 'next/head'; @@ -12,8 +11,6 @@ import Redirect from '@/components/Redirect'; import MainLayout from '@/layouts/MainLayout'; import { store, persistor } from '@/store/store'; -const queryClient = new QueryClient(); - export default function App({ Component, pageProps }: AppProps) { return ( <> @@ -34,17 +31,15 @@ export default function App({ Component, pageProps }: AppProps) { - - - - - - - - - - - + + + + + + + + + From f3d4a214b4d88052f990407255ccb81c204053f1 Mon Sep 17 00:00:00 2001 From: un0211 Date: Wed, 10 Jul 2024 22:59:08 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=9B=A0=20=20fix(#237):=20=ED=95=B8?= =?UTF-8?q?=EB=93=A4=EB=A7=81=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=8A=94=20=EB=8B=A4=EC=8B=9C=20throw,=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=8A=94=20=EC=98=AC=EB=B0=94=EB=A5=B8=20id?= =?UTF-8?q?=20=EC=96=BB=EC=9D=80=20=EB=92=A4=EB=B6=80=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Header/DashboardHeader/MemberProfiles.tsx | 7 +++++-- src/components/Header/DashboardHeader/index.tsx | 2 +- src/components/Redirect/index.tsx | 3 +++ src/containers/dashboard/edit/DashboardModifySection.tsx | 2 +- src/containers/dashboard/edit/InvitedMembersSection.tsx | 7 +++++-- src/containers/dashboard/edit/MembersSection.tsx | 7 +++++-- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/Header/DashboardHeader/MemberProfiles.tsx b/src/components/Header/DashboardHeader/MemberProfiles.tsx index 10ebcaa3..96b21e6b 100644 --- a/src/components/Header/DashboardHeader/MemberProfiles.tsx +++ b/src/components/Header/DashboardHeader/MemberProfiles.tsx @@ -26,8 +26,11 @@ const genMemberProfiles = (members: Member[], distance: number) => // NOTE: 대시보드 헤더 구성원 프로필 목록 컴포넌트 export default function MemberProfiles({ id }: MemberProfilesProps) { - const { data, isLoading, error } = useFetchData(['members', id, 1], () => - getMembersList(Number(id)), + const { data, isLoading, error } = useFetchData( + ['members', id, 1], + () => getMembersList(Number(id)), + false, + !!id, ); if (isLoading) { diff --git a/src/components/Header/DashboardHeader/index.tsx b/src/components/Header/DashboardHeader/index.tsx index 8e59a74a..3649119d 100644 --- a/src/components/Header/DashboardHeader/index.tsx +++ b/src/components/Header/DashboardHeader/index.tsx @@ -22,7 +22,7 @@ export default function DashboardHeader() { data: dashboard, isLoading, error, - } = useFetchData(['dashboard', id], () => getDashboard(id as string)); + } = useFetchData(['dashboard', id], () => getDashboard(id as string), false, !!id); if (isLoading || !id) { return ; diff --git a/src/components/Redirect/index.tsx b/src/components/Redirect/index.tsx index f9a4d958..8be88202 100644 --- a/src/components/Redirect/index.tsx +++ b/src/components/Redirect/index.tsx @@ -26,6 +26,9 @@ export default function Redirect({ children }: { children: React.ReactNode }) { case 404: if (user) redirect('/mydashboard', '접근 권한이 없습니다'); else redirect('/signin', '접근 권한이 없습니다'); + break; + default: + throw error; } } }, diff --git a/src/containers/dashboard/edit/DashboardModifySection.tsx b/src/containers/dashboard/edit/DashboardModifySection.tsx index 8f625636..0a4b959f 100644 --- a/src/containers/dashboard/edit/DashboardModifySection.tsx +++ b/src/containers/dashboard/edit/DashboardModifySection.tsx @@ -70,7 +70,7 @@ export default function DashboardModifySection({ initIsPublic, onPublicChange }: data: dashboard, isLoading, error, - } = useFetchData(['dashboard', id], () => getDashboard(id as string)); + } = useFetchData(['dashboard', id], () => getDashboard(id as string), false, !!id); const { data: favoriteList } = useFetchData( ['favorites', favoriteUserId], diff --git a/src/containers/dashboard/edit/InvitedMembersSection.tsx b/src/containers/dashboard/edit/InvitedMembersSection.tsx index 02c25f7e..1ac93754 100644 --- a/src/containers/dashboard/edit/InvitedMembersSection.tsx +++ b/src/containers/dashboard/edit/InvitedMembersSection.tsx @@ -21,8 +21,11 @@ export default function InvitedMembersSection() { const { id } = router.query; const [currentChunk, setCurrentChunk] = useState(1); - const { data, isLoading, error } = useFetchData(['invitations', id, currentChunk], () => - getDashboardInvitations(Number(id), currentChunk, 5), + const { data, isLoading, error } = useFetchData( + ['invitations', id, currentChunk], + () => getDashboardInvitations(Number(id), currentChunk, 5), + false, + !!id, ); const totalPage = data ? Math.max(1, Math.ceil(data.totalCount / 5)) : 1; diff --git a/src/containers/dashboard/edit/MembersSection.tsx b/src/containers/dashboard/edit/MembersSection.tsx index d3574fec..3061eb5d 100644 --- a/src/containers/dashboard/edit/MembersSection.tsx +++ b/src/containers/dashboard/edit/MembersSection.tsx @@ -24,8 +24,11 @@ export default function MembersSection({ onDeleteMember }: MemberSectionProps) { const { id } = router.query; const [currentChunk, setCurrentChunk] = useState(1); - const { data, isLoading, error } = useFetchData(['members', id, currentChunk], () => - getMembersList(Number(id), currentChunk, 4), + const { data, isLoading, error } = useFetchData( + ['members', id, currentChunk], + () => getMembersList(Number(id), currentChunk, 4), + false, + !!id, ); const totalPage = data ? Math.max(1, Math.ceil(data.totalCount / 4)) : 1; From dafe7b17ee8bdfad8df4cac2e6d1058882280753 Mon Sep 17 00:00:00 2001 From: un0211 Date: Wed, 10 Jul 2024 23:24:45 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=9B=A0=20=20fix(#237):=20queryClient?= =?UTF-8?q?=EA=B0=80=20=EC=BA=90=EC=8B=9C=EB=A5=BC=20=EC=9E=98=20=ED=95=A0?= =?UTF-8?q?=20=EC=88=98=20=EC=9E=88=EA=B2=8C=20=EC=A0=84=EC=97=AD=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Redirect/index.tsx | 22 +++++++--------------- src/pages/_app.tsx | 30 +++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/components/Redirect/index.tsx b/src/components/Redirect/index.tsx index 8be88202..3cbc4378 100644 --- a/src/components/Redirect/index.tsx +++ b/src/components/Redirect/index.tsx @@ -1,4 +1,4 @@ -import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; @@ -10,12 +10,14 @@ import { RootState } from '@/store/store'; // NOTE: 권한에 따라 페이지 이동 export default function Redirect({ children }: { children: React.ReactNode }) { const redirect = useRedirect(); - const router = useRouter(); const { user } = useSelector((state: RootState) => state.user); + const router = useRouter(); const currentPath = router.pathname; // NOTE: QueryCache로 글로벌 콜백 설정 - const queryCache = new QueryCache({ + const queryClient = useQueryClient(); + const queryCache = queryClient.getQueryCache(); + queryCache.config = { onError: (error) => { if (error instanceof AxiosError) { switch (error.response?.status) { @@ -32,17 +34,7 @@ export default function Redirect({ children }: { children: React.ReactNode }) { } } }, - }); - - const queryClient = new QueryClient({ - queryCache, - defaultOptions: { - queries: { - retry: 0, - refetchOnWindowFocus: false, - }, - }, - }); + }; useEffect(() => { // NOTE: 로그인 한 경우 mydashboard를 default로 @@ -67,5 +59,5 @@ export default function Redirect({ children }: { children: React.ReactNode }) { } }, [currentPath, router.query.id]); - return {children}; + return children; } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 218d3ac5..dc94bd8c 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,4 +1,5 @@ import '@/styles/globals.css'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import type { AppProps } from 'next/app'; import Head from 'next/head'; @@ -11,6 +12,15 @@ import Redirect from '@/components/Redirect'; import MainLayout from '@/layouts/MainLayout'; import { store, persistor } from '@/store/store'; +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 0, + refetchOnWindowFocus: false, + }, + }, +}); + export default function App({ Component, pageProps }: AppProps) { return ( <> @@ -31,15 +41,17 @@ export default function App({ Component, pageProps }: AppProps) { - - - - - - - - - + + + + + + + + + + +