diff --git a/src/app/mypage/_components/Fallback.tsx b/src/app/mypage/_components/Fallback.tsx new file mode 100644 index 0000000..6e87e95 --- /dev/null +++ b/src/app/mypage/_components/Fallback.tsx @@ -0,0 +1,11 @@ +import { Spinner } from '@/components/common/spinner'; + +const Fallback = () => { + return ( +
+ +
+ ); +}; + +export default Fallback; diff --git a/src/app/mypage/_components/MyTest.tsx b/src/app/mypage/_components/MyTest.tsx index 92997d2..1f6f647 100644 --- a/src/app/mypage/_components/MyTest.tsx +++ b/src/app/mypage/_components/MyTest.tsx @@ -1,26 +1,26 @@ 'use client'; +import { Suspense } from 'react'; + import { ResultCard, ResultCardContainer } from '@/components/features/test/resultCard'; import { EmptyTest } from '@/components/shared'; import { useGetMyTest } from '@/hooks/test'; +import { Fallback as MyTestFallback } from '.'; + const MyTest = () => { - const { data, status } = useGetMyTest(); + const { data } = useGetMyTest(); return ( - <> + }> - {status === 'pending' ? ( - <> - ) : status === 'error' ? ( - <> - ) : data.length > 0 ? ( + {data.length > 0 ? ( data.map((result) => ) ) : ( )} - + ); }; diff --git a/src/app/mypage/_components/MyVote.tsx b/src/app/mypage/_components/MyVote.tsx index e0b71d0..54b50c1 100644 --- a/src/app/mypage/_components/MyVote.tsx +++ b/src/app/mypage/_components/MyVote.tsx @@ -2,7 +2,7 @@ import dayjs from 'dayjs'; import Link from 'next/link'; -import { useRef } from 'react'; +import { Suspense, useRef } from 'react'; import { Button } from '@/components/common/button'; import { Icon } from '@/components/common/icon'; @@ -14,22 +14,19 @@ import { useDeleteVoteMutation, useGetMyVote } from '@/hooks/vote'; import { VoteType } from '@/types/vote'; import { fromNowOf } from '@/utils/dates'; +import { Fallback as MyVoteFallback } from '.'; + type BottomSheetType = 'askDelete' | 'selectOption'; const MyVote = () => { - const { data, status } = useGetMyVote(); + const { data } = useGetMyVote(); const { mutate: onDelete, isPending } = useDeleteVoteMutation(); const { onOpenSheet, openedSheet, onCloseSheet } = useBottomSheetState(); const deleteTarget = useRef(null); - // TODO Suspense or ssr return ( - <> - {status === 'pending' ? ( - <> - ) : status === 'error' ? ( - <> - ) : data.length > 0 ? ( + }> + {data.length > 0 ? (
{data.map((vote) => ( @@ -114,7 +111,7 @@ const MyVote = () => { ) : ( )} - + ); }; diff --git a/src/app/mypage/_components/index.ts b/src/app/mypage/_components/index.ts index f8445ca..4ca0272 100644 --- a/src/app/mypage/_components/index.ts +++ b/src/app/mypage/_components/index.ts @@ -1,3 +1,4 @@ +export { default as Fallback } from './Fallback'; export { default as MyTest } from './MyTest'; export { default as MyVote } from './MyVote'; export { default as Profile } from './Profile'; diff --git a/src/app/vote/[slug]/_component/Replies.tsx b/src/app/vote/[slug]/_component/Replies.tsx index a4774d3..942d2bc 100644 --- a/src/app/vote/[slug]/_component/Replies.tsx +++ b/src/app/vote/[slug]/_component/Replies.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useCallback, useRef, useState } from 'react'; +import { Suspense, useCallback, useRef, useState } from 'react'; import { ControlTab } from '@/components/common/controlTab'; import { Spinner } from '@/components/common/spinner'; @@ -23,7 +23,7 @@ type Props = { const Replies = ({ voteId }: Props) => { const { data: user } = useGetUser(); - const { status, data: replies } = useGetVoteReplies({ voteId }); + const { data: replies } = useGetVoteReplies({ voteId }); const { mutateAsync: createVoteReplyAsync } = useCreateVoteReplyMutation(); const { mutate: deleteVoteReply } = useDeleteVoteReplyMutation(); const { mutate: toggleLikeVoteReply } = useLikeVoteReplyMutation(); @@ -55,35 +55,30 @@ const Replies = ({ voteId }: Props) => { - {/* TODO: Suspense or SSR */} - {status === 'pending' ? ( -
- -
- ) : status === 'error' ? ( -
에러
- ) : sortedReplyData.length > 0 ? ( -
    - {sortedReplyData.map((reply) => ( - - toggleLikeVoteReply({ voteId: reply.voteId, commentId: reply.commentId }) - } - onDelete={() => - deleteVoteReply({ - commentId: reply.commentId, - voteId: reply.voteId, - }) - } - isWrittenByCurrentUser={reply.userId === user?.userId} - /> - ))} -
- ) : ( - - )} + }> + {sortedReplyData.length > 0 ? ( +
    + {sortedReplyData.map((reply) => ( + + toggleLikeVoteReply({ voteId: reply.voteId, commentId: reply.commentId }) + } + onDelete={() => + deleteVoteReply({ + commentId: reply.commentId, + voteId: reply.voteId, + }) + } + isWrittenByCurrentUser={reply.userId === user?.userId} + /> + ))} +
+ ) : ( + + )} +
{ @@ -95,6 +90,14 @@ const Replies = ({ voteId }: Props) => { ); }; +const ReplyFallback = () => { + return ( +
+ +
+ ); +}; + const NoReplies = () => { return (
diff --git a/src/app/vote/[slug]/_component/VoteDetail.tsx b/src/app/vote/[slug]/_component/VoteDetail.tsx index 7222ce0..30660c5 100644 --- a/src/app/vote/[slug]/_component/VoteDetail.tsx +++ b/src/app/vote/[slug]/_component/VoteDetail.tsx @@ -1,6 +1,6 @@ 'use client'; -import { notFound } from 'next/navigation'; +import { Suspense } from 'react'; import { Button } from '@/components/common/button'; import { Icon } from '@/components/common/icon'; @@ -17,61 +17,61 @@ type Props = { }; const VoteDetail = ({ voteId }: Props) => { - const { status, data } = useGetVoteById(voteId); + const { data } = useGetVoteById(voteId); const { mutate: toggleLike } = useLikeVoteMutation(); return (
- {status === 'pending' ? ( -
- -
- ) : status === 'error' ? ( - notFound() - ) : ( - <> - + }> + - - Q. {data.title} - - - {data.content} - + + Q. {data.title} + + + {data.content} + - - + + - - + + -
- toggleLike({ voteId })} - /> -
- - )} +
+ toggleLike({ voteId })} + /> +
+
); }; +const VoteDetailFallback = () => { + return ( +
+ +
+ ); +}; + export default VoteDetail; diff --git a/src/app/vote/[slug]/page.tsx b/src/app/vote/[slug]/page.tsx index ed7ba20..a1de7e5 100644 --- a/src/app/vote/[slug]/page.tsx +++ b/src/app/vote/[slug]/page.tsx @@ -6,14 +6,14 @@ type Props = { params: { slug: string }; }; -const VoteDetailPage = async ({ params }: Props) => { - const voteId = params.slug; +const VoteDetailPage = ({ params }: Props) => { + const voteId = +params.slug; return ( <> - + - + ); }; diff --git a/src/hooks/test/useGetMyTest.ts b/src/hooks/test/useGetMyTest.ts index ca641ff..56dccf7 100644 --- a/src/hooks/test/useGetMyTest.ts +++ b/src/hooks/test/useGetMyTest.ts @@ -1,10 +1,10 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspenseQuery } from '@tanstack/react-query'; import { donworryApi } from '@/api'; import { queryKey } from '@/api/queryKey'; const useGetMyTest = () => { - return useQuery({ + return useSuspenseQuery({ queryKey: queryKey.test.myResult, queryFn: donworryApi.test.getMyTest, }); diff --git a/src/hooks/vote/useGetMyVote.ts b/src/hooks/vote/useGetMyVote.ts index 4f0f2c9..d4b6f65 100644 --- a/src/hooks/vote/useGetMyVote.ts +++ b/src/hooks/vote/useGetMyVote.ts @@ -1,10 +1,10 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspenseQuery } from '@tanstack/react-query'; import { donworryApi } from '@/api'; import { queryKey } from '@/api/queryKey'; const useGetMyVote = () => { - return useQuery({ + return useSuspenseQuery({ queryFn: donworryApi.vote.getMyVotes, queryKey: queryKey.vote.myVotes(), retry: 1, diff --git a/src/hooks/vote/useGetVoteById.ts b/src/hooks/vote/useGetVoteById.ts index 8e78a26..9de71a4 100644 --- a/src/hooks/vote/useGetVoteById.ts +++ b/src/hooks/vote/useGetVoteById.ts @@ -1,10 +1,10 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspenseQuery } from '@tanstack/react-query'; import { donworryApi } from '@/api'; import { queryKey } from '@/api/queryKey'; export const useGetVoteById = (voteId: number) => { - return useQuery({ + return useSuspenseQuery({ queryKey: queryKey.vote.detail(voteId), queryFn: () => donworryApi.vote.getVoteById({ voteId }), }); diff --git a/src/hooks/vote/useGetVoteReplies.ts b/src/hooks/vote/useGetVoteReplies.ts index ba8c0c8..d851a3c 100644 --- a/src/hooks/vote/useGetVoteReplies.ts +++ b/src/hooks/vote/useGetVoteReplies.ts @@ -1,11 +1,11 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspenseQuery } from '@tanstack/react-query'; import { donworryApi } from '@/api'; import { queryKey } from '@/api/queryKey'; import { GetVoteRepliesRequest } from '@/api/vote/types'; const useGetVoteReplies = ({ voteId }: GetVoteRepliesRequest) => { - return useQuery({ + return useSuspenseQuery({ queryKey: queryKey.vote.reply(voteId), queryFn: () => donworryApi.vote.getVoteReplies({ voteId }), });