[ 상황 ]
- /user/profile/[userId] -> 동적 라우팅으로 특정한 유저의 페이지로 접속하는 상황
- 유저 페이지 자체는 유저가 쓴 게시글 페이지보다는 SEO 중요도는 다소 떨어지지만, 추후 확장을 위해 이미 개발해둔 동적 페이지에서 기능을 구현
- 마이 페이지와 유저 페이지는 한 컴포넌트를 공유하여 사용
(전역에 저장된 나의 loginId와 동적 라우팅으로 접속한 페이지에서 params로 추출한 userId를 비교하여 분기 처리)
[ 개발 환경 ]
- nextjs는 pages router 구조로 개발 중이며 데이터 요청은 Tanstack-Query를 사용합니다.
- 관련 포스팅 : [Next.js 13] SSR로 동적 meta태그 생성하기 (app router)
구현 기능
마이 페이지일 때 메타 태그 (정적 데이터)
유저 페이지일 때 메타 태그 (동적 데이터)
코드 작성
확인해야 할 것
_app.tsx에 아래와 같이 pageProps가 잘 전달되고 있는지 확인한다.
- 모든 컴포넌트가 렌더링 될 때는 이 _app.tsx를 먼저 거쳐가며, 여기서 pageProps에 SSR로 받아온 데이터가 우리가 렌더링할 컴포넌트까지 흘러 들어간다.
- (만약 만약에) 초기세팅 때 삭제했다면 다시 살려두자..!
- nextjs pages 폴더 구조 기준이다.
_app.tsx
const App = ({ Component, pageProps }: AppProps) => {
.
.
.
.
return (
.
.
.
<Component {...pageProps} />
.
.
.
getServerSideProps
109번째 줄의 props로 내 보내는 userId의 값은 UserPage 컴포넌트에서 받아올 수 있다.
- 콘솔을 찍어보면 터미널의 서버 단에서 userId인 'doyu'가 출력되는 것을 확인할 수 있다.
SSR에서 QueryClient를 생성하고, prefetchQuery를 사용해서 기존 회원정보 불러오기 query문을 작성한다.
- apiUser.ts 코드 54번째 줄 참고 (밑에 있음)
apiUser.ts
1. UserPage 컴포넌트 내에서는 SSR에서 받아온 userId로 마이 페이지 여부 함수를 작동시킨다. (16번째 줄)
- 이 때, loginId와 userId가 같으면 /user/mypage로 이동한다.
- loginId : redux/toolkit에 저장된 전역 로그인한 유저의 ID 데이터
- userId: SSR로 받아온 동적 페이지에서 해당 유저의 ID 데이터
2. UserPage 컴포넌트 내에서 기존의 query말고, SSR 회원정보 불러오기(60번째 줄) query로 SSR에서 캐싱된 데이터를 가져온다.
import { QueryClient, dehydrate } from '@tanstack/react-query';
import type { GetServerSideProps } from 'next';
import { ParsedUrlQuery } from 'querystring';
.
.
.
const UserPage({ userId: userIdParam }: { userId: string }) {
const { isLoggedIn, loginId: globalLoginId } = useUserGlobalValue();
useCheckIsMyPageFirst({ userIdParam, globalLoginId });
const {
isLoading: isUserPageLoading,
error: isUserPageError,
data: userPageData,
} = apiUser.useGetUserPage(userIdParam);
.
.
.
export default UserPage;
// 🟣 서버에서 이미 데이터까지 fetch해온 상태에서 렌더링 진행 (SSR)
interface Params extends ParsedUrlQuery {
userId?: string | string[];
}
// 동적으로 추출해온 userId 타입은 아래와 같이 ParsedUrlQuery에서 확장된 Params로 지정해주었다.
export const getServerSideProps: GetServerSideProps = async ({ params }) => {
const { userId }: Params = params || { userId: undefined };
const queryClient = new QueryClient();
await queryClient.prefetchQuery(['userPage'], () => apiUser.getUserPage(userId));
return {
props: {
userId,
dehydratedState: dehydrate(queryClient),
},
};
};
그러면 이렇게 userId와 해당 유저에 해당되는 유저 정보를 잘 받아오는 것을 확인할 수 있다.
메타 태그 생성하기
- 마이페이지일 때는 HeadMeta에 마이 페이지 관련 상수 값을 넣는다. (정적인 값)
- 유저페이지일 때는 HeadMetadp 동적으로 받아온 userPageData의 해당 유저 nickname 값을 넣는다.
.
.
.
return (
.
.
. {isMyPage ? (
<HeadMeta title={USER_META_DATA.MY_PAGE.TITLE} description={USER_META_DATA.MY_PAGE.DESCRIPTION} />
) : (
<HeadMeta
title={USER_META_DATA.USER_PAGE.TITLE}
description={`제로힙 ${userPageData?.nickname}님의 페이지입니다`}
/>
)}
.
.
.
.
이렇게 하면 아래와 같이 닉네임이 출력되는 것을 확인할 수 있다!
참고
728x90
'📌 PROJECT > 2307 제로힙 : 가계부 SNS' 카테고리의 다른 글
Meta 태그 컴포넌트 및 중복 출력 이슈 (0) | 2023.10.06 |
---|---|
프로젝트 4주차(데모데이) KPT : 최선의 선빵 - 지옥의 CORS (0) | 2023.08.01 |
프로젝트 3주차 KPT : 기승전결의 ‘전’ (0) | 2023.07.21 |
프로젝트 2주차 KPT : 나는 혼자가 아니다 (0) | 2023.07.15 |
프로젝트 1주차 KPT : 모두가 같은 마음일 수는 없다. 그리고.. (0) | 2023.07.05 |