인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

한 입 크기로 잘라먹는 Next.js(15+)

2.8) 페이지별 레이아웃 설정하기

getLayout을 왜 사용하는 건가요?? (5:20)

해결된 질문

24.08.22 12:47 작성

·

213

·

수정됨

1

이번 강의에서 페이지별 레이아웃을 사용할 때, 레이아웃이 필요한 컴포넌트에 getLayout 메소드를 추가해서 사용합니다

// 1
export default function Home() {
  return <h1 className={style.h1}>인덱스</h1>;
}

Home.getLayout = (page: ReactNode) => {
  return <SearchableLayout>{page}</SearchableLayout>;
};
// 2
export default function Home() {
  return <SearchableLayout>
           <h1 className={style.h1}>인덱스</h1>
         </SearchableLayout>;
}
// _app.tsx
// a
type NextPageWithLayout = NextPage & {
  getLayout?: (page: ReactNode) => ReactNode;
};

export default function App({
  Component,
  pageProps,
}: AppProps & { Component: NextPageWithLayout }) {
  const getLayout = Component.getLayout ?? ((page: ReactNode) => page);

  return <GlobalLayout>{getLayout(<Component {...pageProps} />)}</GlobalLayout>;
}

// b
export default function App({
  Component,
  pageProps,
}: AppProps) {
  return <GlobalLayout><Component {...pageProps} /></GlobalLayout>;
}

 

2번째 코드처럼 사용하면 app 컴포넌트(b)와 레이아웃이 필요한 컴포넌트(2) 둘 다 더 짧게 사용할 수 있을 거 같은데, getLayout 메소드를 사용해야 하는건지 질문드립니다

 

  • 그냥 표준처럼 사용 되는 건지??

  • 페이지 컴포넌트와 레이아웃 컴포넌트를 분리하기 위해서인지??

  • 레이아웃이 필요한 컴포넌트에서 레이아웃을 부모 컴포넌트로 사용하면 해당 컴포넌트간 상태 유지 관련 문제가 있는건지??

    질문 드립니다

답변 1

1

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

2024. 08. 22. 13:09

안녕하세요 전상원님 이정환입니다.

getLayout 메서드를 사용하는 이유는 강의에서 말씀드렸듯 페이지별 레이아웃을 설정해주기 위함입니다. 우리 강의의 예시로 구체적으로 말씀드리면 Home 컴포넌트가 담당하는 index 페이지만의 레이아웃을 설정해주기 위함인거죠

Home.getLayout = (page: ReactNode) => {
  return <SearchableLayout>{page}</SearchableLayout>;
};

위 코드 블럭처럼 Home 컴포넌트에 getLayout이라는 메서드를 설정해두게 되면

인덱스 페이지 역할을 하는 Home 컴포넌트에 getLayout이라는 메서드가 추가 됩니다.

(참고로 함수에 프로퍼티를 추가하는 과정은 자바스크립트 기본 문법 중 하나입니다)

그러면 이제 사용자가 인덱스 페이지에 접속하게 되면 위와 같이 getLayout이라는 메서드가 추가된

Home 컴포넌트가 페이지 컴포넌트로써 작용하게 될겁니다.

 

export default function App({ Component, pageProps }) {
  const getLayout = Component.getLayout;

  return getLayout(<Component {...pageProps} />);
)
 

따라서 App 컴포넌트에서 위와 같이 현재 페이지 컴포넌트인 "Component"의 getLayout 메서드를 꺼내오게 되면 만약 현재 페이지 컴포넌트가 Home 컴포넌트일 때에는 위 코드블록에 설정해둔 그 getLayout 메서드가 잘 꺼내와지게 될 겁니다.

그리고 이때의 getLayout 메서드는 컴포넌트에 특정 레이아웃을 적용하는 메서드이므로 위와 같이 getLayout 메서드를 호출하고 Compoennt를 인수로 전달한 결과를 반환하면 그 결과 별도의 레이아웃이 적용된 Home 컴포넌트가 화면에 렌더링 될 겁니다.

구체적인 내용은 강의에서 이미 설명해드렸으니 다시 한번 참고해보시는것도 좋을 것 같습니다.
또는 아래의 공식문서 링크를 참고해보셔도 좋을 것 같습니다.

https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts#per-page-layouts

이해가 어려우시다면 구체적으로 어떤 부분이 혼란스러운지 구체적으로 알려주시면 추가 답글드리겠습니다.

전상원님의 프로필 이미지

2024. 08. 22. 13:48

export default function Home() {
  return <SearchableLayout>
           <h1 className={style.h1}>인덱스</h1>
         </SearchableLayout>;
}

제가 질문하고 싶었던 내용은

NextJS에서는 getLayout 메서드를 페이지 컴포넌트에 추가해서 페이지별로 레이아웃을 사용합니다.(ok)

Q. 위의 코드처럼 레이아웃을(not global) getLayout없이 페이지 컴포넌트의 부모 컴포넌트로 사용해도 똑같이 사용할 수 있는데,

**반드시 getLayout 메서드를 사용해서 부분 레이아웃을 사용해야 하는건지?

이 부분에 대해 질문 드리고 싶었습니다.


When navigating between pages, we want to persist page state (input values, scroll position, etc.) for a Single-Page Application (SPA) experience.

This layout pattern enables state persistence because the React component tree is maintained between page transitions. With the component tree, React can understand which elements have changed to preserve state.

페이지를 탐색 할 때 지속 SPA (Single-Page Application) 경험을위한 페이지 상태 (입력 값, 스크롤 위치 등).

이 레이아웃 패턴은 반응 구성 요소 트리가 페이지 전환간에 유지되므로 **상태 지속성을 가능하게합니다. 구성 요소 트리를 사용하면 React는 상태를 유지하기 위해 변경된 요소를 이해할 수 있습니다.

공식 문서에서는 상태 유지를 위해 사용하는 것으로 보입니다.

감사합니다

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

2024. 08. 22. 14:04

안녕하세요 앗 궁금하신 점이 요거였군요 😀

export default function Home() {
  return <SearchableLayout>
           <h1 className={style.h1}>인덱스</h1>
         </SearchableLayout>;
}

질문주신대로 위 코드처럼 페이지 컴포넌트의 부모 컴포넌트로 사용해도 레이아웃의 UI자체는 동일하게 렌더링 할 수 있습니다.

그러나 위 방법에는 큰 단점이 하나 있는데요 바로 페이지 이동시에 레이아웃 컴포넌트가 무조건 언마운트 된다는 점 입니다.

위 방법으로 레이아웃을 적용하면 동일한 레이아웃을 사용하는 페이지로 이동하게 되더라도 무조건 레이아웃이 언마운트되었다가 다시 마운트 되기 때문에 불필요한 렌더링 리소스를 낭비하게 됩니다.

따라서 만약 레이아웃 컴포넌트내에서 State라도 사용하고 있었다면 페이지가 이동될 때 마다 State도 초기화 될 것입니다. 이렇게 동작하는 이유는 페이지 이동시에는 현재 페이지 컴포넌트가 언마운트 되기 때문입니다.

 

그러나 반면 getLayout 메서드를 활용해 App 컴포넌트에서 일괄적으로 중첩 레이아웃을 적용하도록 설정해주시면 이런 문제는 발생하지 않습니다.

이유는 페이지 이동이 아무리 발생한다고 해도 App 컴포넌트가 언마운트 되지는 않기 때문입니다. App 컴포넌트는 업데이트만 될 뿐이죠 따라서 동일한 레이아웃을 사용하는 페이지간의 이동을 적은 렌더링 리소스만으로 처리할 수 있어집니다.

그리고 그럼으로써 State의 초기화까지 방지할 수 있습니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기