[삽질기#2] 잃어버린 getLayout을 찾아서..

이호정·2023년 1월 20일
0

삽질기

목록 보기
2/2

next.js에서 여러 페이지에 동일한 레이아웃을 적용하고 싶다면, getLayout을 이용하게 된다.

자세한 사용방법은 공식문서를 참고하자

페이지마다 다른 레이아웃을 적용하고 싶을 때는 레이아웃이 필요한 컴포넌트의 getLayout을 따로 정의하고 _app.tsx를 아래와 같이 설정하면 된다.

export default function MyApp({ Component, pageProps }) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout || ((page) => page)

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

나의 경우에는 반대로 getLayout이 따로 정의되지 않으면 공통 레이아웃을 적용하고, 그렇지 않은 페이지에서만 getLayout을 정의해 페이지별 레이아웃을 적용시켰었다.

이전까지 잘해왔는데, 새롭게 개발한 페이지에 새로운 레이아웃을 적용하려고 getLayout을 정의했는데, 공통된 레이아웃으로 적용되는 문제가 생겼다.

원인 분석

내가 할줄아는 분석은 딱 하나, console.log() 이다. _app.tsx에서 console.log(Component.getLayout) 을 추가하여 확인해봤다.

이전의 다른 페이지에서는 아래와 같이 잘 나왔는데, 왜그런걸까..

원인 발견..!

잘되는 이전 페이지와 다른 점이 뭘까 열심히 비교해보니, 새로운 페이지에서는 withRouter로 컴포넌트를 감싸서 export하고 있는 것을 발견했다.

일전에 다른 문제로 useRouter 대신 사용해본답시고 적용했던 코드였는데, 결국 useRouter를 사용하게 되었기에 결과적으로 필요없는 코드였다.

필요없는 코드니까 지우고 다시 실행해보니 새로운 레이아웃이 잘 적용된 모습을 볼 수 있었다!!

조금 더 파헤쳐보자..

결과적으로 해결되었으니, 진짜로 그런지 한번 확인해보자.

next.js의 모듈에 들어가 withRouter 부분을 찾았다.

// next/dist/client/with-router.js
... 전략 ...

function withRouter(ComposedComponent) {
    function WithRouterWrapper(props) {
        return /*#__PURE__*/ _react.default.createElement(ComposedComponent, Object.assign({
            router: (0, _router).useRouter()
        }, props));
    }
  
    WithRouterWrapper.getInitialProps = ComposedComponent.getInitialProps;
    WithRouterWrapper.origGetInitialProps = ComposedComponent.origGetInitialProps;
    if (process.env.NODE_ENV !== 'production') {
        const name = ComposedComponent.displayName || ComposedComponent.name || 'Unknown';
        WithRouterWrapper.displayName = `withRouter(${name})`;
    }
    return WithRouterWrapper;
}

... 후략 ...

보이는 바와 같이 인자로 넘겨받은 컴포넌트의 getLayout 함수는 전달해주지 않고 있었다.

그러니 무조건 undefined가 출력될 수 밖에..!

getLayout은 왜 안보일까?

결론부터 말하자면, getLayout은 Next.js에서 제공하는 api가 아니다.
공식문서를 참고해보면 알 수 있듯이 getLayout은 페이지 별로 다른 레이아웃을 지정하기 위해 사용하는 함수를 이용한 방법일 뿐
getLayout 이라는 이름으로 정의된 api는 next.js 내부를 아무리 뜯어봐도 찾을 수 없다.

조금만 천천히 생각해봤다면, 호기롭게 PR을 날리는 등의 수치스러운 짓은 하지 않았을 텐데...

수치스럽지만, 안고 나아가야할 과거 아니겠나, 값진 경험이었다.

0개의 댓글