본문 바로가기
개발/Next.js

Custom App Component (.pages/_app.js)

by 안뇽! 2022. 1. 29.
반응형

 

모든 홈페이지에서 공통으로 보이는 헤더를 표현할때 리액트에서는 src/App.js에 다음과 같이 작성했다.

import React from "react";
import { Route, Switch } from "react-router-dom";
import Header from "./components/Header/Header";

export const App = () => {
..(생략)..
  return (
    <>
      <Header />
      <Switch>
        <Route exact path="/" component={MainPage} />
        <Route exact path="/home" component={Home} />
        <Route path="/mypage" component={MyPage} />
        <Route exact path="/detailpage/:id" component={DetailPage} />
        <Route path="/user/kakao/callback" component={KakaoRedirectHandler} />
      </Switch>
    </>
  );
};

이런식으로 모든 화면에서 렌더링 될 Header, 그리고 react-router-dom 라이브러리를 활용하여 동적 페이지 라우팅을 구현하였다.

 

하지만 Next.js에서는 파일이름이 곧 url이 되어 자동으로 동적 페이지 라우팅이 된다.

 

Header도 리액트의 App.js처럼 어떤 한 공통의 컴포넌트에 넣고 싶었다.

 

이러한 고민으로 main.js를 만들어보았지만 url이 바뀌면서 렌더링되는 컴포넌트 자체가 달라졌다.

 

때문에 모든 컴포넌트에서 비효율적으로 Header를 복붙해야 하는건가?? 이건 아닐것같은데.. 라는 생각을 했다.

 

노마드 코더 강의를 보니 pages/_app.js 라는 파일을 이용하여 Header를 한번만 렌더링 시킬 수 있었다.

 

무조건 파일이름을 _app.js로 만들어야한다. 그게 프레임워크 next.js의 규칙이다.

 


pages/_app.js

다음과 같이 작성을 하였다.

 

_app.js에는 기본 템플릿으로 필요한 컴포넌트들을 작성하여 복붙을 피할 수 있다.

_app.js에 NavBar를 리턴하기 전에는 about.js, index.js NavBar를 복붙해야 했다.

우선 아래 gif처럼 만들었다는것을 언급한 후 _app.js에 대해 계속 이야기를 해보자.

 

App Component

App Component는 Next.js가 모든 페이지를 렌더링할 수 있게 하는, 리액트의 src/index.js 같은 곳이다.

 

이건 기본적으로 next.js 프레임워크 깊은 곳에 작성되어 있는 로직이다. 우린 그저 pages폴더안에 _app.js를 만들어주기만 하면 된다.

 

무조건 폴더이름이 _app.js 이어야 한다.(타입스크립트라면 .tsx)

 

이렇게 되면 Next.js는 pages/index.js가 렌더링 되기 전에 pages/_app.js를 먼저 렌더링시킨다.

 

_app.js에서는 아래 코드에 의해 pages의 다른 컴포넌트들이 렌더링된다.

(특별한 조작이 없다면 './' 에 해당하는 pages/index.js 가 렌더링 될 것이다.)

 

// pages/_app.js
// 이 방식은 그냥 Next.js 프레임워크가 정한 방식이다.
// Next.js는 자동으로 _app.js를 가장 먼저 확인한다.

export default function App({ Component, pageProps }) {

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

때문에 _app.js에 전역스타일링이나, 공통컴포넌트를 넣어두면 그 _app.js를 기반으로 UI가 구성된다.

 

아래 코드는 가장 위에 NavBar를 ,가장아래에는 "하이하이" 문구를 렌더링 시킨다.

전역 스타일링은 a태그의 글자색이 하얀색이 되도록 하였다.

import NavBar from "../components/NavBar";

export default function App({ Component, pageProps }) {
  return (
    <div>
      <NavBar />
      <Component {...pageProps} />
      <span>"하이하이"</span>
      <style jsx global>{`
        a {
          color: white;
        }
      `}</style>
    </div>
  );
}

아래 gif를 보면 url이 바뀌어도(페이지 이동) NavBar와 "하이하이" 문구는 계속 렌더링된다.

이는 index.js와 about.js에 복붙했기 때문이 아니라 _app.js에서 NavBar와 "하이하이"를 렌더링 시키기 때문이다.

 

반응형