-
Notifications
You must be signed in to change notification settings - Fork 1
[Refactor] 타인 프로필 페이지 SSR 적용 및 이미지 최적화 #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
088e745
e4dbbab
affaead
9804e96
9e30cb0
1cde934
52fd41b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. api 관련해서는 프로젝트 전체적으로 리펙토링이 필요할거같아요
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞아요.. SSR의 경우에는 서버 컴포넌트에서 받아야해서 .. 멘토링시간에 물어보고 싶네요..!! |
||
| 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; | ||
|
|
@@ -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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 경우에는 그럼 동작 순서가 어떻게 되는거에요?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 다시 찾아보면서 한거라 ㅋㅋㅋㅋ 일단 제가 정리해놓거는 이정도입니당 QueryClient를 생성하고, prefetchQuery를 이용해 API 요청을 미리 수행. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😎
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" | ||
| /> | ||
| ), | ||
| )} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
주석은 없애도 될거같아요