next.js 설치, pages, Link, useRouter, style jsx
next.js 사용법 정리
청약닷컴 에서 기존에 router 로 작업하던 것을 next.js 로 수정했다.
설치
프로젝트 폴더에서 아래 명령어로 next.js 기반의 app을 생성한다.
npx create-next-app@latest .
이때 typescript 와 ESLint 의 사용여부를 묻는데 프로젝트에 맞춰서 선택한다.
ESLint 는 Javascript 의 문법을 확인해 주는 도구이다.
CRA 로 app 생성시에는 ESLint 가 자동으로 설치된다.
app 을 생성하면 기존 CRA 로 생성한 것과 다르게 pages 와 styles 폴더, next.config.js 가 있다.
프로젝트 실행
local 에서 프로젝트를 실행할때 아래 명령어를 사용한다.
npm run dev
run 시킨 후 localhost:3000 에서 개발중인 프로젝트를 확인할 수 있다.
pages
pages 폴더 내 파일을 생성하면 파일 및 폴더명에 맞춰서 자동으로 router 를 설정해 페이지를 생성한다.
pages 폴더의 index 파일은 사이트의 index 페이지가 되고, pages/about.js 파일은 사이트도메인/about 의 경로를 갖는다.
단독 페이지가 아닌 컴포넌트를 생성하고 싶다면 pages 외부에 별도로 components 등의 폴더를 만들어 작성한다.
Link
next.js 환경에서 페이지를 이동하고 싶다면 next 의 link 컴포넌트를 사용한다.
Link 컴포넌트는 자동으로 a 태그로 렌더링된다.
import Link from 'next/link';
<Link href='URL'>Button</Link>
useRouter()
useRouter()
로 현재 경로에 대한 정보를 받을 수 있다.
먼저 아래와 같이 import 및 사용선언을 한 후 사용한다.
import { useRouter } from 'next/router';
const router = useRouter();
이렇게 선언을 하면 router 에 다양한 정보값들이 담긴다.
-
pathname
현재 페이지 경로를 반환한다.
도메인/about 경로의 페이지라면 ‘/about’ 이 값이 된다. -
query
쿼리스트링을 객체형태로 반환된다.
도메인/about?id=1&name=myName 이라면 {id: ‘1’, name: ‘myName’} 을 값으로 가질 것이다.
기본값은 {} 이다.
router.back()
이전 페이지로 돌아간다.
router.push()
jsx 가 아닌 스크립트에서 페이지를 이동시키고 싶을 때 사용한다.
router.push('/about?id=1');
아래와 같이 인자를 객체 형태로 작성해 쿼리스트링을 객체 상태로 전달할 수도 있다.
router.push(
{
pathname: '/about',
query: { id: 1 }
}
);
두번째 인자로 경로를 기재하면 기재되지 않는 쿼리스트링은 경로에 표시되지 않고 값으로만 전달된다.
router.push(
{
pathname: '/about',
query: { id: 1 }
},
'/about'
);
style.jsx
next.js 는 기본적으로 style jsx 기능을 지원한다.
<style jsx>{`
div{
width: 100px;
height: 100px;
}
`}</style>
style jsx
태그를 컴포넌트에서 지정하면 해당 컴포넌트 내부의 스타일링이기 때문에 전역 스타일을 지정할수 없다.
공통되는 컴포넌트의 스타일링은 _app.js 을 생성해 공통 컴포넌트로 묶어서 처리할 수 있다.
_app.js
next.js 환경에서 모든 페이지에 기본적으로 사용되는 마스터 페이지이다.
공통적으로 반복되는 내용을 작성한다.
function App({ Component, pageProps }) {
return (
<>
<공통컴포넌트 />
<Component {...pageProps} />
</>
)
};
Component 는 각 페이지에서 출력되는 컴포넌트를 의미하며 pageProps 로 페이지 호출 시의 Props 를 출력 컴포넌트에 전달한다.
공통적인 스타일 또한 App 컴포넌트 내부에서 global 하게 지정할 수 있다.
function App({ Component, pageProps }) {
return (
<>
<공통컴포넌트 />
<Component {...pageProps} />
<style jsx global>{`
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
`}</style>
</>
)
};
코드 분리
컴포넌트에 css와 공통 컴포넌트를 불러오는 코드를 모두 작정해 내용이 너무 길어지면 가독성이 떨어지므로 파일을 분리한다.
css
styles 폴더에 css 파일을 별도로 생성해 해당 파일을 컴포넌트에서 import 한다.
// pages/_app.js
import '../styles/globals.css';
function App({ Component, pageProps }) {
return (
<>
<공통컴포넌트 />
<Component {...pageProps} />
</>
)
};
컴포넌트
_app.js 내에서 공통으로 불러오는 부분을 Layout 요소를 components/Layout.js 파일으로 이동시킨다.
// components/Layout.js
import '../styles/globals.css';
import Layout from '../components/Layout';
function App({ children }) {
return (
<>
<Header />
{children}
<Footer />
</>
)
};
_app.js 에서 Component 를 Layout 의 Prop 으로 전달해 Layout 의 children 부분에 출력되게 한다.
// pages/_app.js
import Layout from '../components/Layout';
function App({ Component, pageProps }) {
return (
<>
<Layout>
<Component {...pageProps} />
</Layout>
</>
)
};