- 메인 페이지에서만 작업을 하다가 최초로 페이지를 만드는 순간!
역할 흐름
- 유저가 메인페이지에서 카드 하나를 클릭
- 상세 페이지 컴포넌트는 서버 컴포넌트임에도 불구하고, url의 parameter를 받을 수 있다.
- parameter를 받아서, prisma로 DB에서 해당 listingId에 해당하는 숙박정보를 가져온다. (API 콜 안함)
- 대신에 Date 타입 이슈때문에,
createdAt
, updatedAt
, emailVerified
를 toISOString
메서드를 사용해서 string 타입
으로 변경후 가져오도록 한다.
export default async function getListingById(params: IParams) {
try {
const { listingId } = params;
const listing = await prisma.listing.findUnique({
where: {
id: listingId,
},
include: {
user: true,
},
});
if (!listing) {
return null;
}
return {
...listing,
createdAt: listing.createdAt.toISOString(),
user: {
...listing.user,
createdAt: listing.user.createdAt.toISOString(),
updatedAt: listing.user.updatedAt.toISOString(),
emailVerified: listing.user.emailVerified?.toISOString() || null,
},
};
} catch (error: any) {
throw new Error(error);
}
}
서버 컴포넌트인 Listing
Page
// 서버컴포넌트에서도 다행히도 params에 접근할 수는 있다.
async function ListingPage({ params }: { params: IParams }) {
// 서버 컴포넌트 이기 때문에 DB에 직접 조회해서 가져올 수 있음.
const listing = await getListingById(params);
const currentUser = await getCurrentUser();
// listing이 없을때...
if (!listing) {
return (
<ClientOnly>
<EmptyState />
</ClientOnly>
);
}
return (
<ClientOnly>
<ListingClient listing={listing} currentUser={currentUser} />
</ClientOnly>
);
}
상세정보를 가져온후 화면에 렌더링 하는 과정
- 컴포넌트
- ListingClient : ListingPage의 최상단 컴포넌트
- ListingHead : 사진, 타이틀,
- ListingInfo : 호스트, 메타정보, 지도
- ListingCategory : 카테고리 (icon, label, description)