Skip to content

Commit

Permalink
[REFACTOR] useSuspenseQuery 및 Suspense 적용 (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhsung23 authored Apr 3, 2024
1 parent c83b205 commit 72ec961
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 107 deletions.
11 changes: 11 additions & 0 deletions src/app/mypage/_components/Fallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Spinner } from '@/components/common/spinner';

const Fallback = () => {
return (
<div className="flex size-full flex-col items-center justify-center">
<Spinner />
</div>
);
};

export default Fallback;
16 changes: 8 additions & 8 deletions src/app/mypage/_components/MyTest.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Suspense fallback={<MyTestFallback />}>
<ResultCardContainer>
{status === 'pending' ? (
<></>
) : status === 'error' ? (
<></>
) : data.length > 0 ? (
{data.length > 0 ? (
data.map((result) => <ResultCard key={result.id} result={result} />)
) : (
<EmptyTest />
)}
</ResultCardContainer>
</>
</Suspense>
);
};

Expand Down
17 changes: 7 additions & 10 deletions src/app/mypage/_components/MyVote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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<BottomSheetType>();
const deleteTarget = useRef<VoteType['id'] | null>(null);

// TODO Suspense or ssr
return (
<>
{status === 'pending' ? (
<></>
) : status === 'error' ? (
<></>
) : data.length > 0 ? (
<Suspense fallback={<MyVoteFallback />}>
{data.length > 0 ? (
<div className="mt-3xs flex flex-col gap-3xs">
{data.map((vote) => (
<VoteCard key={vote.id}>
Expand Down Expand Up @@ -114,7 +111,7 @@ const MyVote = () => {
) : (
<EmptyVote />
)}
</>
</Suspense>
);
};

Expand Down
1 change: 1 addition & 0 deletions src/app/mypage/_components/index.ts
Original file line number Diff line number Diff line change
@@ -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';
65 changes: 34 additions & 31 deletions src/app/vote/[slug]/_component/Replies.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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();
Expand Down Expand Up @@ -55,35 +55,30 @@ const Replies = ({ voteId }: Props) => {

<Notice text="댓글을 사용할 때는 타인을 존중해야합니다." />

{/* TODO: Suspense or SSR */}
{status === 'pending' ? (
<div className="flex h-full items-center justify-center py-lg">
<Spinner />
</div>
) : status === 'error' ? (
<div>에러</div>
) : sortedReplyData.length > 0 ? (
<ul className="flex h-full flex-col px-2xs py-3xs">
{sortedReplyData.map((reply) => (
<Reply
key={reply.commentId}
reply={reply}
onLikeToggle={() =>
toggleLikeVoteReply({ voteId: reply.voteId, commentId: reply.commentId })
}
onDelete={() =>
deleteVoteReply({
commentId: reply.commentId,
voteId: reply.voteId,
})
}
isWrittenByCurrentUser={reply.userId === user?.userId}
/>
))}
</ul>
) : (
<NoReplies />
)}
<Suspense fallback={<ReplyFallback />}>
{sortedReplyData.length > 0 ? (
<ul className="flex h-full flex-col px-2xs py-3xs">
{sortedReplyData.map((reply) => (
<Reply
key={reply.commentId}
reply={reply}
onLikeToggle={() =>
toggleLikeVoteReply({ voteId: reply.voteId, commentId: reply.commentId })
}
onDelete={() =>
deleteVoteReply({
commentId: reply.commentId,
voteId: reply.voteId,
})
}
isWrittenByCurrentUser={reply.userId === user?.userId}
/>
))}
</ul>
) : (
<NoReplies />
)}
</Suspense>

<ReplyInput
onSubmit={async (content) => {
Expand All @@ -95,6 +90,14 @@ const Replies = ({ voteId }: Props) => {
);
};

const ReplyFallback = () => {
return (
<div className="flex h-full items-center justify-center py-lg">
<Spinner />
</div>
);
};

const NoReplies = () => {
return (
<div className="flex h-full items-center justify-center py-lg">
Expand Down
92 changes: 46 additions & 46 deletions src/app/vote/[slug]/_component/VoteDetail.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -17,61 +17,61 @@ type Props = {
};

const VoteDetail = ({ voteId }: Props) => {
const { status, data } = useGetVoteById(voteId);
const { data } = useGetVoteById(voteId);
const { mutate: toggleLike } = useLikeVoteMutation();

return (
<section className="h-fit px-2xs">
{status === 'pending' ? (
<div className="flex min-h-[480px] items-center justify-center">
<Spinner />
</div>
) : status === 'error' ? (
notFound()
) : (
<>
<VoteExtraDetail
voteId={data.id}
author={data.user}
views={data.views}
category={data.category}
/>
<Suspense fallback={<VoteDetailFallback />}>
<VoteExtraDetail
voteId={data.id}
author={data.user}
views={data.views}
category={data.category}
/>

<Typography type="title2" className="mt-3xs text-gray-1000">
Q. {data.title}
</Typography>
<Typography type="body3" className="mb-3xs mt-4xs text-gray-500">
{data.content}
</Typography>
<Typography type="title2" className="mt-3xs text-gray-1000">
Q. {data.title}
</Typography>
<Typography type="body3" className="mb-3xs mt-4xs text-gray-500">
{data.content}
</Typography>

<VoteCard>
<VoteCard.Header
closeDate={data.closeDate}
voter={data.voters}
fontColor="text-gray-600"
fontSize="text-xs"
/>
<VoteCard>
<VoteCard.Header
closeDate={data.closeDate}
voter={data.voters}
fontColor="text-gray-600"
fontSize="text-xs"
/>

<Voting voteId={data.id} selected={data.selected} selections={data.selections} />
</VoteCard>
<Voting voteId={data.id} selected={data.selected} selections={data.selections} />
</VoteCard>

<div className="mb-3xs mt-sm flex justify-between">
<LikeButton
isLiked={data.isLiked}
likeCount={data.likes}
onClick={() => toggleLike({ voteId })}
/>
<Button
iconOnly
Icon={<Icon icon="share" color="gray-300" />}
variant="empty"
className="!p-0"
/>
</div>
</>
)}
<div className="mb-3xs mt-sm flex justify-between">
<LikeButton
isLiked={data.isLiked}
likeCount={data.likes}
onClick={() => toggleLike({ voteId })}
/>
<Button
iconOnly
Icon={<Icon icon="share" color="gray-300" />}
variant="empty"
className="!p-0"
/>
</div>
</Suspense>
</section>
);
};

const VoteDetailFallback = () => {
return (
<div className="flex min-h-[480px] items-center justify-center">
<Spinner />
</div>
);
};

export default VoteDetail;
8 changes: 4 additions & 4 deletions src/app/vote/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<>
<VoteDetail voteId={Number(voteId)} />
<VoteDetail voteId={voteId} />
<Divider height={8} />
<Replies voteId={Number(voteId)} />
<Replies voteId={voteId} />
</>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/test/useGetMyTest.ts
Original file line number Diff line number Diff line change
@@ -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,
});
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/vote/useGetMyVote.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/vote/useGetVoteById.ts
Original file line number Diff line number Diff line change
@@ -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 }),
});
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/vote/useGetVoteReplies.ts
Original file line number Diff line number Diff line change
@@ -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 }),
});
Expand Down

0 comments on commit 72ec961

Please sign in to comment.