Next.js 13버전 에서는 app 경로를 이용해서 페이지 구성과 라우팅 기능을 구현할 수 있다 .app 경로를 기준으로 app/post 폴더가 있다면 브라우저 상에서 /post 페이지로 들어가면 post안에 있는 page.jsx안에 있는 내용이 나타나게 된다.
export default function post() {
return <h1>Post 페이지입니다.</h1>;
}
폴더명을 기준으로 라우팅을 하는 것이기 때문에 컴포넌트 함수 명은 njnjdjqkqke 이런식으로 작명을 해도 라우팅은 잘 동작한다.
export default function njnjdjqkqke() {
return <h1>Post 페이지입니다.</h1>;
}
가장 하단에 위치한 page.tsx는 서비스의 가장 첫 화면의 page.tsx를 위치시키면 된다.
export default function RootLayout({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(() => new QueryClient());
// pathname === chat 일 경우 채팅 버튼 삭제
const pathname = usePathname();
return (
<RecoilRoot> // 리코일 전역 관리(로그인,모달 등)
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}> //공통 테마 객체(스타일)
<GlobalStyles /> //글로벌 css
<html>
<body>
<Header />
{pathname !== "/chat" && <ChatBtn />}
{children}
</body>
</html>
</ThemeProvider>
</QueryClientProvider>
</RecoilRoot>
);
}
layout.jsx에서는 해당 페이지의 레이아웃을 구성할 수있는데 {children}안에 들어가는 내용들이 page.jsx안의 내용들로 들어가게 된다.
body 안쪽에 Header가 전역적으로 보여지게 되고 Chat컴포넌트가 항상 보여지게 되는 구조다. Chat은 Recoil을 이용해 로그인 시에만 화면에 보이게 끔 설정 해둔 것으로 알고 있다.
이번에 맡은 파트에서 게시글 상세 부분은 app/post/detail 이런식의 폴더 구조를 가지고 있다. post/write라는 경로도 쓰기 위해서 post 안쪽에 두 폴더를 만들어 프로젝트를 진행했다.
Next.js에서는 동적 라우팅을 어떻게 해야 하는지에 대한 개념을 모르고 있었다. 프로젝트를 진행하면서 며칠 간의 기한을 정하고 퍼블리싱을 마무리 하기로해서 퍼블리싱 마친 후에 공부하면서 알아보기로 했다.
post/detail/page.tsx 에서 게시글 상세에 대한 퍼블리싱을 진행했고 post/write/page.tsx에서 게시글 작성에 대한 퍼블리싱을 진행했다. 화면의 기본적인 구성을 마친 후 기능 구현을 하면서 post/detail/1, post/detail/2, 처럼 :path값이 필요해졌고 이 부분을 공식 문서를 찾아보았다.
동적인 라우팅은 NextJs 공식 문서 Next.js Dynamic Routes 에서 볼 수 있다.
NextJs공식 문서에서는 동적인 부분은 대괄호로 감싸줌으로써 가능하다고 설명하고 있다. [id]나 [slug]처럼 동적인 부분들은 Components에게 params prop로 전달되어진다.
예를 들어 app/post/detail/[id]/pages.tsx로 경로를 지정하면 되는 것이다.
id를 사용하느냐 slug를 사용하느냐는 문자열을 post/detail/[문자열] 처럼 특정한 문자열을 URL로 사용하고 싶을 때 사용하고, [id]는 일반적인 식별 post/detail/1,2,3,4 처럼 유일한 번호를 이용해 특정 레코드나 객체를 식별하고자 할 때 사용한다고 이해했다.
나는 post/detail/1 이런식의 url을 원하므로 [id]를 사용하여 폴더구조를 수정하였다.
만약에 예를 들어 app/post/detail/nextjs-튜토리얼, app/post/detail/nextjs-피자만들기 이런식의 url을 사용하고 싶었다면 [slug]를 사용하여야 한다. 사용자가 url을 보고 포스트의 내용을 직관적으로 반영할 수 있기 때문에 url을 공유할 때 더 많은 클릭을 유도할 수 있기 때문이다.
주의할 점은 같은 제목의 포스트가 여러개 있을 경우 slug가 중복될 수 있다는 점을 유의해야 한다. 이 부분은 slug 뒤에 숫자를 추가하는 등 여러 방법을 생각해 봐야한다.
params는 일반적으로 웹 개발에서 URL 경로의 동적 세그먼트를 나타내기 위해 사용한다.
detail/[id]/page.tsx 파일에 params는 함수 컴포넌트 PostDetail의 매개변수로 전달되는 객체로 id라는 속성이 포함 되어있다.
export default function PostDetail({ params: { id: number } }) {
이 부분에서 params를 구조 분해하여 그 안의 id를 추출하고 있고, id는 숫자(number) 타입임을 명시해주고 있다. ( params 즉 동적 세그먼트 값을 id로 작용하게 하겠다.)
const response = await axiosRequest.requestAxiosResData<Posting>("get", `/articles/${params.id}`);
params.id는 API 요청 URL의 일부로 사용되는데 응답 값의 id(number)값을 참조해 정보를 가져오기위한 요청을 보내고 있다.
useEffect(() => {
fetchPostDetail();
}, [params.id]);
useEffect 훅을 사용하여 params.id가 변경될 때마다 fetchPostDetail 함수를 다시 호출하여 해당 id의 게시물을 불러오고 있다.