글 작성자: 택시 운전사
반응형
  • 이 글은 Next.js의 공식 튜토리얼을 번역한 글입니다.
  • 오역 및 오탈자 발견시 댓글로 제보해주시면 감사하겠습니다.

Next.js는 결국 페이지라는 것을 알 것입니다. 리액트 컴포넌트를 내보내고 해당 컴포넌트를 pages 디렉토리 안에 넣으면 페이지를 만들 수 있습니다. 그 결과로 파일명에 기반한 고정된 URL을 얻을 수 있습니다.

내보내진 페이지들은 자바스크립트 모듈이기 때문에, 다른 자바스크립트 컴포넌트도 불러올 수 있습니다.

무슨 자바스크립트 프레임워크를 쓰던지 이와 같은 기능을 기대할 것입니다.

이번 수업에서 우리는 공통된 헤터 컴포넌트를 만들고 여러 페이지에서 이를 사용할 것입니다. 마지막으로는 레아아웃 컴포넌트를 구현하고 이것이 어떻게 여러 페이지가 어떻게 보일 지를 정하는 데 도움을 줄 것입니다.

시작해봅시다!

셋업

다음 수업을 따라오기위해 간단한 Next.js 앱이 있어야합니다. 이전 수업의 작업으로 계속하거나 다음 예시 앱을 다운로드합니다.

git clone https://github.com/zeit/next-learn-demo.git
cd next-learn-demo
cd 2-using-shared-components

다음 명령어로 실행가능합니다.

npm install
npm run dev

헤더 컴포넌트 만들기

앱에 사용할 헤더 컴포넌트를 만들어봅시다. components/Header.js파일에 다음과 같이 작성해봅시다.

import Link from 'next/link';

const linkStyle = {
  marginRight: 15
};

const Header = () => (
  <div>
    <Link href="/">
      <a style={linkStyle}>Home</a>
    </Link>
    <Link href="/about">
      <a style={linkStyle}>About</a>
    </Link>
  </div>
);

export default Header;

이 컴포넌트는 앱에서 사용가능한 두 개의 페이지에 대한 링크를 포함하고 있습니다. 또한 시각적으로 보기 쉽게 링크를 약간 스타일링 했습니다.

헤더 컴포넌트 사용하기

다음으로, 이 컴포넌트를 불러오고 우리 페이지에서 사용해봅시다. index.js 페이지에서 사용하고 싶다면 아래와 같이 작성합니다.

import Header from '../components/Header';

export default function Index() {
  return (
    <div>
      <Header />
      <p>Hello Next.js</p>
    </div>
  );
}

about.js 페이지에서도 똑같이할 수 있습니다.

이 시점에서 앱을 http://localhost:3000/로 이동하면 새로운 헤더가 보이고 두 페이지간에 이동을 할 수 있을 것입니다.

약간의 수정을 해봅시다.

  • 현재 돌아가고 있는 앱을 멈춥니다.
  • components 디렉토리 이름을 comps로 바꿉니다.
  • ../components/Header대신 ../comps/Header에서 헤더를 불러옵니다.
  • 앱을 다시 시작합니다.

작동합니까?
A. 네
B. 아니요. "Component not found."라는 에러를 던집니다.
C. 아니요. "Component needs to be in the components directory."라는 에러를 던집니다.
D. 아니요. "comps is an invalid directory."라는 에러를 던집니다.

컴포넌트 디렉토리

예, 잘 작동합니다.

특별한 이름의 디렉토리에 컴포넌트를 넣을 필요는 없습니다. 디렉토리 이름은 어떤 것이든 가능하죠. 특별한 이름의 디렉토리는 /pages/public뿐입니다.

pages 디렉토리 안에 컴포넌트를 생성할 수도 있습니다.

헤더 컴포넌트로 가는 다이렉트 URL이 필요없기 때문에 여기서는 하지 않겠습니다.

레이아웃 컴포넌트

앱에서 우리는 여러 페이지에서 공통된 스타일을 사용할 것입니다. 이러한 목적을 가지고 우리는 공통된 레이아웃 컴포넌트를 만들고 각 페이지에서 사용할 수 있습니다. 예제를 확인해봅시다.

components/MyLayout.js에 다음과 같이 작성해주세요.

import Header from './Header';

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
};

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {props.children}
  </div>
);

export default Layout;

이렇게하면, 이 레이아웃을 페이지에 다음과 같이 사용할 수 있습니다.

// pages/index.js

import Layout from '../components/MyLayout';

export default function Index() {
  return (
    <Layout>
      <p>Hello Next.js</p>
    </Layout>
  );
}
// pages/about.js

import Layout from '../components/MyLayout';

export default function About() {
  return (
    <Layout>
      <p>This is the about page</p>
    </Layout>
  );
}

기억하세요, http://localhost:3000에서 앱을 접근하여 어떻게 보이는 지 확인할 수 있습니다.

이제 {props.children}을 레이아웃에서 제거하고 앱에서 어떤 일이 벌어지는 지 확인해봅시다.

앱에서 무슨 일이 벌어졌나요?
A. 아무 일도 일어나지 않을 것입니다.
B. 페이지에 내용이 모두 사라질 것입니다.
C. "Layout needs some content."라는 에러를 던질 것이다.
D. 브라우저 컴포넌트를 위한 경고 메시지를 띄울 것이다.

Child 컴포넌트 렌더링하기

만약 {props.children}을 지운다면, 레이아웃 컴포넌트는 아래와 같이 Layout 요소 안에 넣은 내용을 렌더링하지 않을 것입니다.

export default function About() {
  return (
    <Layout>
      <p>This is the about page</p>
    </Layout>
  );
}

이것은 레아아웃 컴포넌트를 생성하는 방법 중 하나일 뿐입니다. 그리고 여기 다른 여러가지 방식들이 있습니다.

방법 1 - High Order 컴포넌트로서의 레이아웃

// components/MyLayout.js

import Header from './Header';

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
};

const withLayout = Page => {
  return () => (
    <div style={layoutStyle}>
      <Header />
      <Page />
    </div>
  );
};

export default withLayout;
// pages/index.js

import withLayout from '../components/MyLayout';

const Page = () => <p>Hello Next.js</p>;

export default withLayout(Page);
// pages/about.js

import withLayout from '../components/MyLayout';

const Page = () => <p>This is the about page</p>;

export default withLayout(Page);

방법 2 - prop으로서의 페이지 내용

// components/MyLayout.js

import Header from './Header';

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
};

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {props.content}
  </div>
);

export default Layout;
// pages/index.js

import Layout from '../components/MyLayout.js';

const indexPageContent = <p>Hello Next.js</p>;

export default function Index() {
  return <Layout content={indexPageContent} />;
}
// pages/about.js

import Layout from '../components/MyLayout.js';

const aboutPageContent = <p>This is the about page</p>;

export default function About() {
  return <Layout content={aboutPageContent} />;
}

컴포넌트 사용하기

이번 수업에서 공유된 컴포넌트를 위한 두 개의 사용 예시를 알아보았다.

  1. 공통된 헤더 컴포넌트로서
  2. 레이아웃으로서

스타일링, 페이지 레이아웃 그리고 원하는 다른 목적을 위한 컴포넌트로 사용할 수 있다. 추가적으로 NPM 모듈에서 컴포넌트를 불러와서 사용할 수도 있다.

반응형