Skip to content

Commit

Permalink
[#603] [내 프로필] ErrorBoundary 제거 (#604)
Browse files Browse the repository at this point in the history
* fix: 비로그인 내 프로필 페이지 컨탠츠 gap 수정

* fix: ErrorBoundary 제거

* refactor: 내 책장 프리뷰 query의 data값을 보장하도록 useQueryWithSuspense를 적용

* refactor: 불필요한 isSuccess 제거 및 LayoutShift 문제 해결

* chore: 불필요한 query 옵션 제거
  • Loading branch information
hanyugeon authored Jun 2, 2024
1 parent 59aa92c commit 5f083c7
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 143 deletions.
2 changes: 1 addition & 1 deletion src/app/profile/me/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const MyProfileForUnAuth = () => {
return (
<>
<TopHeader text="Profile" />
<div className="flex flex-col gap-[2rem]">
<div className="flex flex-col gap-[3rem]">
<div className="mb-[2rem] flex items-center gap-[1rem]">
<Avatar size="large" />
<div className="flex-grow">
Expand Down
7 changes: 4 additions & 3 deletions src/queries/bookshelf/useMySummaryBookShelfQuery.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import bookshelfAPI from '@/apis/bookshelf';
import { useQuery } from '@tanstack/react-query';
import type { QueryOptions } from '@/types/query';
import type { APIBookshelf } from '@/types/bookshelf';
import type { QueryOptions } from '@/types/query';

import useQueryWithSuspense from '@/hooks/useQueryWithSuspense';
import bookShelfKeys from './key';

const useMySummaryBookshelfQuery = (options?: QueryOptions<APIBookshelf>) =>
useQuery(
useQueryWithSuspense(
bookShelfKeys.summary('me'),
() => bookshelfAPI.getMySummaryBookshelf().then(({ data }) => data),
options
Expand Down
8 changes: 2 additions & 6 deletions src/v1/profile/bookShelf/MyProfileBookshelfContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ import ProfileBookshelfPresenter from './ProfileBookshelfPresenter';
import useMySummaryBookshelfQuery from '@/queries/bookshelf/useMySummaryBookShelfQuery';

const MyProfileBookshelfContainer = () => {
const { isSuccess, data } = useMySummaryBookshelfQuery({
suspense: true,
});
const { data } = useMySummaryBookshelfQuery();

if (!isSuccess) return null;

return <ProfileBookshelfPresenter {...data}></ProfileBookshelfPresenter>;
return <ProfileBookshelfPresenter {...data} />;
};

export default MyProfileBookshelfContainer;
48 changes: 5 additions & 43 deletions src/v1/profile/bookShelf/ProfileBookShelf.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,14 @@
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import type { APIUser } from '@/types/user';

import MyProfileBookshelfContainer from './MyProfileBookshelfContainer';
import UserProfileBookshelfContainer from './UserProfileBookshelfContainer';
import useMounted from '@/hooks/useMounted';
import Loading from '@/v1/base/Loading';

const ProfileBookShelf = ({ userId }: { userId: 'me' | APIUser['userId'] }) => {
const mounted = useMounted();

if (!mounted) return null;

return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileBookShelfSkeleton />}>
{userId === 'me' ? (
<MyProfileBookshelfContainer />
) : (
<UserProfileBookshelfContainer userId={userId} />
)}
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
return userId === 'me' ? (
<MyProfileBookshelfContainer />
) : (
<UserProfileBookshelfContainer userId={userId} />
);
};

export default ProfileBookShelf;

const ProfileBookShelfSkeleton = () => {
return (
<div className="flex animate-pulse flex-col gap-[2rem]">
<div className="h-[2.7rem] w-[5rem] bg-placeholder" />

<div className="flex h-[13.2rem] items-center justify-center">
<Loading />
</div>
</div>
);
};
8 changes: 2 additions & 6 deletions src/v1/profile/bookShelf/UserProfileBookshelfContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ const UserProfileBookshelfContainer = ({
}: {
userId: APIUser['userId'];
}) => {
const { isSuccess, data } = useUserSummaryBookshelfQuery(userId, {
suspense: true,
});
const { data } = useUserSummaryBookshelfQuery(userId);

if (!isSuccess) return null;

return <ProfileBookshelfPresenter {...data}></ProfileBookshelfPresenter>;
return <ProfileBookshelfPresenter {...data} />;
};

export default UserProfileBookshelfContainer;
68 changes: 28 additions & 40 deletions src/v1/profile/group/ProfileGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,44 @@
import useMounted from '@/hooks/useMounted';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';

import { APIUser } from '@/types/user';
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';

import Skeleton from '@/v1/base/Skeleton';
import ProfileGroupContainer from './ProfileGroupContainer';

const ProfileGroup = ({ userId }: { userId: 'me' | APIUser['userId'] }) => {
const mounted = useMounted();

if (!mounted) return null;

return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileGroupSkeleton />}>
<ProfileGroupContainer userId={userId} />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
<SSRSafeSuspense fallback={<ProfileGroupSkeleton />}>
<ProfileGroupContainer userId={userId} />
</SSRSafeSuspense>
);
};

export default ProfileGroup;

const ProfileGroupSkeleton = () => {
return (
<div className="flex animate-pulse flex-col gap-[0.6rem]">
<div className="flex h-[2.7rem] w-[6rem] bg-placeholder" />
<div className="flex gap-[1rem] overflow-scroll">
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem] bg-placeholder" />
</div>
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem]bg-placeholder" />
</div>
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem] bg-placeholder" />
<Skeleton>
<div className="flex flex-col gap-[1.5rem]">
<Skeleton.Text fontSize="2xlarge" width="6rem" />
<div className="flex gap-[1rem] overflow-scroll">
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
</div>
</div>
</div>
</Skeleton>
);
};
4 changes: 1 addition & 3 deletions src/v1/profile/group/ProfileGroupContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ const ProfileGroupContainer = ({
}: {
userId: 'me' | APIUser['userId'];
}) => {
const { isSuccess, data } = useMyGroupsQuery({ suspense: true });
const { data } = useMyGroupsQuery();
const {
data: { userId: myId },
} = useMyProfileQuery({ enabled: userId === 'me' });

const isMeOwner = (ownerId: number) => ownerId === myId;

if (!isSuccess) return null;

return (
<ProfileGroupPresenter userId={userId} isGroupOwner={isMeOwner} {...data} />
);
Expand Down
64 changes: 23 additions & 41 deletions src/v1/profile/info/ProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,42 @@
import { ReactNode, Suspense } from 'react';
import type { APIUser } from '@/types/user';

import SSRSafeSuspense from '@/components/SSRSafeSuspense';

import Skeleton from '@/v1/base/Skeleton';
import MyProfileContainer from './MyProfileInfoContainer';
import UserProfileInfoContainer from './UserProfileInfoContainer';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { ErrorBoundary } from 'react-error-boundary';
import type { APIUser } from '@/types/user';
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import useMounted from '@/hooks/useMounted';

type ProfileInfoProps = {
children?: ReactNode;
userId: 'me' | APIUser['userId'];
};

const ProfileInfo = ({ userId, children }: ProfileInfoProps) => {
const mounted = useMounted();

if (!mounted) return null;

const ProfileInfo = ({ userId }: ProfileInfoProps) => {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileInfoSkeleton />}>
{userId === 'me' ? (
<MyProfileContainer />
) : (
<UserProfileInfoContainer userId={userId} />
)}
{children && children}
</Suspense>
</ErrorBoundary>
<SSRSafeSuspense fallback={<ProfileInfoSkeleton />}>
{userId === 'me' ? (
<MyProfileContainer />
) : (
<UserProfileInfoContainer userId={userId} />
)}
</QueryErrorResetBoundary>
</SSRSafeSuspense>
);
};

export default ProfileInfo;

const ProfileInfoSkeleton = () => {
return (
<div className="mb-[2rem] flex animate-pulse flex-col gap-[2rem]">
<div className="flex gap-[0.8rem]">
<div className="h-[2.1rem] w-[3.8rem] rounded-lg bg-placeholder" />
<div className="h-[2.1rem] w-[7.6rem] rounded-lg bg-placeholder" />
</div>
<div className="flex items-center gap-[1rem]">
<div className="h-[7rem] w-[7rem] rounded-full bg-placeholder" />
<div className="h-[2.7rem] w-[11rem] bg-placeholder" />
<Skeleton>
<div className="mb-[2rem] flex flex-col gap-[2rem]">
<div className="flex gap-[0.8rem]">
<Skeleton.Rect width="3.8rem" height="2.1rem" />
<Skeleton.Rect width="10.4rem" height="2.1rem" />
</div>
<div className="flex items-center gap-[1rem]">
<Skeleton.Circle size="large" />
<Skeleton.Text fontSize="2xlarge" width="18rem" />
</div>
</div>
</div>
</Skeleton>
);
};

0 comments on commit 5f083c7

Please sign in to comment.