Before you learn
🔗 [NextJS] hard / soft navigation
🔗 [NextJS] Intercepting Routes
[NextJS] Parallel Routes
NextJS의 13.3 버전에 추가된 기능입니다.
영상
instagram의 사진을 눌렸을 때 모달이 나타나지만,
해당 모달이 나타났을 때 새로고침을 하면 해당 사진 페이지로 이동합니다.
Intercepting Routes와 Parallel Routes를 사용하면 instagram의 모달처럼 구현할 수 있습니다.
장∙단점
굳이 Parallel Routes를 사용할 필요는 없다.
직접 페이지에 컴포넌트를 여러 개 넣으면 되기 때문이다.
하지만, Parallel Routes를 사용하면 각각의 Loading 파일을 작성하기에 용이하다.
(= 스켈레톤을 따로 구현할 수 있다.)
설명
Parallel Routes를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링 할 수 있습니다.
Slot(슬롯)
Parallel Routes는 슬롯을 사용하여 생성됩니다.
슬롯은 폴더명 앞에 '@'를 붙여주면 됩니다.
위의 이미지에서는 @analytics, @team 두 개의 슬롯을 가지고 있습니다.
해당 슬롯을 레이아웃을 통해 함께 렌더링 할 수 있습니다.
// app/layout.tsx
export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
404 Error
Parallel Routes를 사용한 후,
새로고침을 하면 404 에러가 발생한다.
왜 에러가 발생되는지 살펴보자.
정답은 NextJS가 페이지를 렌더링하는 방식에 있다.
// app/layout.tsx
export default function Layout({
children,
potato,
}:{
children: React.ReactNode
potato: React.ReactNode
}) {
return (
<>
{potato}
{children}
</>
);
}
@potato 슬롯 안에 page.tsx 파일만 있다고 가정하자.
우리는 Layout에 매번 potato, children prop를 항상 렌더링 해야 된다고 하였다.
만약 '/home' 페이지로 간다면,
children prop의 경우,
app 폴더 하위의 모든 폴더들을 둘러보며, home 폴더의 page 파일을 가져온다.
potato prop로 마찬가지로,
potato 슬롯 폴더 안에서, home 폴더를 찾는다.
하지만, potato 슬롯 폴더 안에는 page 파일만 있으므로, home 폴더를 찾지 못해, 404 에러가 발생한다.
이와 같은 에러를 해결하기 위해 2가지 방법이 있다.
1. potato 슬롯 안에 /home과 같이 특정 URL로 이동하는 폴더명을 만들고, 그 안에 page 파일을 만든다.
만약, 1번을 적용시켰다고 가정하자, 그러나 동일한 레이아웃을 적용받는 '/profile' 페이지가 있고,
그 페이지로 이동하면 또 다시 potato 폴더 안의 profile 폴더를 찾지 못해 404 에러가 발생할 것이다.
해당 방법을 적용하려면 Parallel Route 안에서, 즉 potato 슬롯 폴더 안에 모든 페이지의 복사본을 생성해야 되기 때문이다.
그렇기 때문에 해당 방법은 적절하지 않다.
2. Default Routes를 사용한다.
potato 슬롯 폴더 안에 default 파일을 만든다.
해당 파일명은 page, loading 파일처럼 특별한 파일명이기에 꼭 default.jsx(tsx)로 만들어야 한다.
default 파일은 파일명 말 그대로 기본으로 렌더링 될 페이지이다.
이동하려는 페이지와 그 페이지에 해당되는 폴더가 해당 슬롯 폴더 하위에 없다면,
default.jsx(tsx)를 보여준다.
export default function Default() {
return null;
}
의문점
default.jsx 파일을 만들기 전에 다른 페이지로 이동하면 404 에러가 발생하지 않고,
해당 페이지에서 새로고침을 해야 404 에러가 발생할까?
// app/layout.tsx
export default function Layout({
children,
potato,
}:{
children: React.ReactNode
potato: React.ReactNode
}) {
return (
<>
{potato}
{children}
</>
);
}
위의 사진에서 @team 슬롯이 없고, @analytics가 @potato로 변경되었다고 가정하자.
'/' 페이지에서 '/home' 페이지로 링크를 눌러 이동하면,
이것은 soft navigation이다.
NextJS의 Link 컴포넌트를 사용하는 navigation이다.
페이지에 접속하면 '/' 페이지에서 Parallel Route는 슬롯 안의 page.jsx(tsx)를 찾아서 매칭되고,
'/' 페이지에서는 정상적으로 동작한다.
children prop 내부의 링크를 눌려서
'/' 페이지에서 '/home' 페이지로 이동한 경우,
soft navigation 이므로, 화면에서 변경된 부분만 렌더링 한다.
즉, Parallel Route는 다시 렌더링 되지 않는다.
하지만, 여기서 새로고침을 하면, 다시 전부 재렌더링 되기에,
Parallel Route 슬롯 안의 'home' 폴더를 찾을 수 없으므로 404 에러가 발생하게 된다.
요약
Parallel Route를 활성화하고,
Layout에게 Parallel Route를 렌더링 하고 싶다고 작성한다.
사용자가 특정 URL로 이동하는 순간
NextJS는 윗 코드에서는 2개의 페이지 컴포넌트를 찾는다.
1. Parallel Route 폴더 안에서 접속하려는 특정 URL과 매칭되는 페이지 컴포넌트를 찾아 보여준다.
접속하려는 특정 URL과 매칭되는 컴포넌트를 찾을 수 없다면, 404 에러가 발생한다.
하지만, 슬롯 안에 default 파일이 있으면, default 파일을 매칭시킨다.
2. children 파일 안에서 접속하려는 특정 URL과 매칭되는 페이지 컴포넌트를 찾아 보여준다.
Reference
🔗 Next.JS 공식문서 (Parallel Routes)
Next Step
🔗 [Next.JS] default.js