목차
Using Shared Components
앞에서 Next.js에서 페이지를 만드는 방법에 대해 알게 되었습니다. 우리는 react 컴포넌트를 pages 폴더에 넣어서 페이지를 만들 수 있었습니다. pages폴더의 파일 이름은 url로 접근 할 수 있습니다.
pages는 자바스크립트 모듈임으로 다른 자바스크립트 컴포넌트를 넣을 수도 있습니다. 이것은 다른 자바스크립트 프레임워크도 가능할 거라고 생각합니다.
이번 강의에서는 공통 헤더 컴포넌트를 만들어서 여러 페이지에서 사용할 것입니다. 마지막에는 Layout 컴포넌트를 만들고 여러 페이지의 레이아웃을 어떻게 잡을지 살펴 보도록 하겠습니다
Setup
아래의 Next앱을 시작해 주세요. 이전 강의에서 받으셨다면 git clone은 건너 뛰어 주세요
git clone https://github.com/zeit/next-learn-demo.git
cd next-learn-demo
cd 2-using-shared-components
완료가 되었다면 http://localhost:3000 으로 접속해주세요
Create the Header Component
components 폴더를 만들고 Header.js 파일을 생성해 주세요. components폴더는 pages폴더 안이 아닌 루트경로에 생성해야 합니다.
파일을 생성 후 아래의 내용을 입력해주세요
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;
이 컴포넌트에는 이전에 만들었던 페이지에 대한 링크가 있습니다. 보기 쉽게 하기 위해 약간의 style이 추가 되어 있습니다.
Using the Header component
이제 pages/index.js 컴포넌트에 위에 만들었던 컴포넌트를 가지고 와서 사용해봅시다
import Header from '../components/Header'
export default function Index() {
return (
<div>
<Header />
<p>Hello Next.js</p>
</div>
)
}
pages/about.js에서도 동일한게 작업을 한다면 http : // localhost : 3000 / 에서 Header 컴포넌트를 통해 페이지를 이동할 수 있게 됩니다.
components폴더 이름을 comps로 수정한 후 index.js와 about.js에서 import 경로를 '../comps/Header'로 설정해주어도 정상적으로 작동합니다.
즉, import할 컴포넌트가 특별한 디렉토리에 있을 필요는 없습니다. 디렉토리의 이름은 무엇이든 가능합니다. pages폴더 안에 컴포넌트를 생성할 수도 있습니다.
하지만 코드의 가독성을 위해 폴더 이름과 트리 구조를 잘 생각할 필요는 있습니다.
Next.js에서 특수한 디렉토리는 '/pages'와 '/static'뿐 입니다.
The Layout Component
앱에서는 다양한 페이지에서 공통적인 스타일을 사용하는 경우가 많습니다. 따라서 각각의 페이지에서 공통적으로 사용할 Layout컴포넌트를 생성 할 것입니다.
'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 / 에 접속해서 확인하면 공통된 레이아웃이 적용된 걸 확인 할 수 있습니다.
Using Shared Components
components/MyLayout.js에서 {props.children}을 제거하면 어떻게 될까요?
당연히 받은 props가 렌더되지 않으니 내용이 표시 되지 않습니다.
이 방법 말고도 Layout 컴포넌트를 만드는 방법은 몇가지가 더 있습니다. 다른 방법에 대해서도 알아봅시다.
Method 1 - Layout as a Higher Order Component
// 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
withLayout의 첫번재 인자로 Page 컴포넌트를 받고 {props.children} 대신 <Page /> 컴포넌트가 추가 되었습니다
// 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)
페이지 컴포넌트들에서 컴포넌트를 정의하고 withLayout의 인자로 넣어 줍니다
Method 2 - Page content as a 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
props로 content를 받아서 렌더링 합니다
// 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} />
}
jsx를 변수에 직접 저장해서 Layout 컴포넌트에 content로 props를 내려줍니다.
Using Components
이번 장에서는 컴포넌트를 공유하는 방법에 두가지에 대해서 알아보았습니다.
1. Header를 공통 컴포넌트로 만들기
2. Layout을 컴포넌트화 하기
스타일, 레이아웃, 기타 원하는 컴포넌트를 사용할 수 있습니다. npm 모듈 또한 사용할 수 있습니다.
Next js 튜토리얼 4편 : 동적 페이지
Next js 튜토리얼 7편 : 컴포넌트 스타일링
Next js 튜토리얼 8편 : 배포