Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ jobs:

- name: Corepack 활성화
run: corepack enable

- name: pnpm 설치
run: corepack prepare pnpm@latest --activate


- name: 캐시 종속성
id: cache
Expand Down
1 change: 1 addition & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const nextConfig: NextConfig = {
hostname: 'zzikzzik-bucket.s3.ap-northeast-2.amazonaws.com',
},
],
formats: ['image/avif', 'image/webp'], // AVIF 우선 적용
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석은 없애도 될거같아요

},
};

Expand Down
23 changes: 23 additions & 0 deletions src/apis/UserProfile/getUserProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axios from 'axios';
import { API_ENDPOINTS } from '@/constants/ApiEndpoints';

const apiUrl = process.env.NEXT_PUBLIC_API_URL;

export const getUserProfile = async (userId: number, token: string) => {
try {
const response = await axios.get(
apiUrl + API_ENDPOINTS.AUTH.USER_PROFILE(userId),
{
headers: {
token: token,
'Content-Type': 'application/json',
Accept: '*/*',
},
},
);
return response.data;
} catch (error) {
console.error('❌ API 요청 실패:', error);
throw new Error('사용자 프로필을 가져오는 중 문제가 발생했습니다.');
}
};
Comment on lines +1 to +23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api 관련해서는 프로젝트 전체적으로 리펙토링이 필요할거같아요
통합되어있는 느낌이 아니라서 다음 회의 때 의논해봐야겠어요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요.. SSR의 경우에는 서버 컴포넌트에서 받아야해서 .. 멘토링시간에 물어보고 싶네요..!!

24 changes: 22 additions & 2 deletions src/app/(route)/userProfile/[userId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import {
dehydrate,
HydrationBoundary,
QueryClient,
} from '@tanstack/react-query';
import { cookies } from 'next/headers';
import { PageContainer } from '@/components/common/PageContainer';
import { UserProfileContent } from '@/components/UserProfile/UserProfileContent';
import { UserProfileHeader } from '@/components/UserProfile/UserProfileHeader';
import { QUERY_KEYS } from '@/constants/QueryKeys';
import { getUserProfile } from '@/apis/UserProfile/getUserProfile';

interface UserProfileProps {
userId: string;
Expand All @@ -13,10 +21,22 @@ export default async function userProfile({
}) {
const { userId } = await params;

const cookieStore = await cookies();
const token = cookieStore.get('token')?.value || '';

const queryClient = new QueryClient();

await queryClient.prefetchQuery({
queryKey: [QUERY_KEYS.USER_PROFILE, Number(userId)],
queryFn: () => getUserProfile(Number(userId), token),
});

return (
<PageContainer>
<UserProfileHeader userId={userId} />
<UserProfileContent userId={userId} />
<HydrationBoundary state={dehydrate(queryClient)}>
<UserProfileHeader userId={userId} />
<UserProfileContent userId={userId} />
</HydrationBoundary>
</PageContainer>
);
}
Comment on lines +24 to 42
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 경우에는 그럼 동작 순서가 어떻게 되는거에요?
전에 공부 했었는데 아작도 100%는 이해 못했어요 ㅋㅋㅋ

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 다시 찾아보면서 한거라 ㅋㅋㅋㅋ 일단 제가 정리해놓거는 이정도입니당

QueryClient를 생성하고, prefetchQuery를 이용해 API 요청을 미리 수행.
서버에서 가져온 데이터를 dehydrate(queryClient)를 통해 직렬화하여 클라이언트로 전달.
클라이언트에서 HydrationBoundary를 통해 데이터를 재사용, 추가적인 API 호출 없이 빠르게 렌더링.

35 changes: 15 additions & 20 deletions src/components/UserProfile/UserProfileContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,43 @@
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { useUserProfileQuery } from '@/hooks/apis/Auth/useUserProfileQuery';
import { Spinner } from '@/components/common/Spinner';

interface UserProfileContent {
userId: string;
}

export const UserProfileContent = ({ userId }: UserProfileContent) => {
const { completeResponses, isLoading } = useUserProfileQuery(Number(userId));
const { completeResponses } = useUserProfileQuery(Number(userId));

const router = useRouter();

const handleClick = (completeId: number) => {
router.push(`/completes/${completeId}`);
};

if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center">
<Spinner className="size-28" />
</div>
);
}

return (
<div className="mt-8 grid grid-cols-3 gap-8">
{completeResponses.map((complete) =>
complete.completePic ? (
<Image
<div
key={complete.completeId}
sizes="100vw"
width={48}
height={48}
className="flex h-109 w-full rounded-4"
priority
src={complete.completePic}
alt="인증한 이미지"
className="relative aspect-square w-full overflow-hidden rounded-4"
onClick={() => handleClick(complete.completeId)}
/>
>
<Image
priority
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 하는게맞는지는 모르겠네용 ㅎㅎ
감삼다!! 빌드오류 이거 어떡하죠 ㅋㅋㅋ

style={{ objectFit: 'cover' }}
className="rounded-4"
src={complete.completePic}
alt="인증한 이미지"
/>
</div>
) : (
<div
key={complete.completeId}
className="flex h-109 w-full rounded-4 bg-gray-200"
className="flex aspect-square w-full rounded-4 bg-gray-200"
/>
),
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/UserProfile/UserProfileHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const UserProfileHeader = ({ userId }: UserProfileHeader) => {
<Image
width={48}
height={48}
sizes="100vw"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="flex size-64 rounded-full"
priority
src={profilePic}
Expand Down
Loading