export default function Home() {
return (
<div>
<h1></h1>
</div>
)
}
pages > about.js
const about = () => {
return (
<div>
<h1>About</h1>
</div>
)
}
export default about
pages 폴더 안에 파일 생성 후 url에 /파일명을 붙여주면 라우팅 됨
pages > index.js
import Head from 'next/head'
export default function Home() {
return (
<div>
<Head>
<title></title>
<meta name='keywords' content='...' />
</Head>
</div>
헤더, 푸터, 메뉴와 같이 매 페이지마다 보여야하는 것들은 Layout 컴포넌트를 만들어서 쓰면 편리
components > Layout.js
페이지를 레이아웃으로 감싸기 위해 children을 props로 전달
const Layout = ({ children }) => {
return (
...
{children}
...
)
}
pages > _app.js
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
components > Nav.js
import Link from 'next/link'
const Nav = () => {
return (
<nav>
...
<Link href='/'>Home</Link>
...
<Link href='/about'>About</Link>
...
레이아웃에 import
components > Header.js
pages > _document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Data fetching에 사용할 수 있는 세 가지의 메소드가 있음
pages > index.js
Jsonplaceholder라는 API를 통해 가상 데이터를 이용해서 리스트 형태로 출력해볼 것임
export const getStaticProps = async () => {
const res = await fetch('... url ...')
const articles = await res.json()
return {
props: {
articles
}
}
}
이렇게 단순히 객체 형태로 props와 함께 리턴하면 됨
components > ArticleList.js
데이터가 출력될 리스트는 따로 컴포넌트를 분리하여 props를 통해 데이터 전달
const ArticleList = ({articles}) => {
return (
<div>
{articles.map((article) => (
<h3>{article.title}</h3>
))}
</div>
)
}
export default ArticleList
pages > index.js
import Head from 'next/head'
import ArticleList from '../components/ArticleList'
export default function Home({articles}) {
return (
<div>
...
<ArticleList articles={articles} />
</div>
components > ArticleItem.js
리스트에 표시될 데이터를 조금 더 수정하여 컴포넌트를 생성했음
import Link from 'next/link'
const ArticleItem = ({article}) => {
return (
<Link href="/article/[id]" as={`/article/${article.id}`}>
<a>
<h3>{article.title} →</h3>
<p>{article.body}</p>
</a>
</Link>
)
}
export default ArticleItem
components > ArticleList.js
import ArticleItem from './ArticleItem'
const ArticleList = ({articles}) => {
return (
<div>
{articles.map((article) => (
<ArticleItem article={article} />
))}
</div>
)
}
export default ArticleList
ArticleItem에서 Link를 사용했기 때문에 이제 List에서 각 목록을 클릭하게 되면 url이 중첩된 루트처럼 나타날 것임
하지만 설정을 안해줬으므로 페이지는 404임 ㅋㅋ
중첩 라우팅을 하는 건 너무나 간단하다
이렇게 우리가 설정할 url의 경로를 그대로 따라 폴더를 만들어주면 됨
pages > article > [id] > index.js
이 index.js가 우리 article의 싱글 페이지가 될 것
import {useRouter} from 'next/router'
const article = () => {
const router = useRouter()
const {id} = router.query
return <div> This is article {id} </div>
}
이렇게 하면 각 id에 맞게 표시될 것임
import {useRouter} from 'next/router'
const article = ({article}) => {
//const router = useRouter()
//const {id} = router.query
return <div> This is article {article.id} </div>
}
export const getServerSideProps = async (context) => {
const res = await fetch(`...url...${context.params.id}`)
const article = await res.json()
return {
props: {
article
}
}
}
getStaticProps와 짝으로 써야 함
export const getStaticProps = async (context) => {
const res = await fetch(`...url...${context.params.id}`)
const article = await res.json()
return {
props: {
article
}
}
}
export const getStaticPaths = async () => {
const res = await fetch(`...url...`)
const articles = await res.json()
const ids = articles.map(article => article.id)
const paths = ids.map(id => ({params: {id: id.toString()}}))
return {
paths,
fallback: false
}
}
위에서 jsonplaceholder를 통해 가상 데이터를 끌어와 사용했던 걸 우리가 정보를 직접 작성해서 API로 만들어 사용할 수 있음
기존에 있는 hello.js는 삭제하고 새롭게 생성
api > articles > idnex.js
데이터베이스 파일인 data.js를 최상위 루트에 가져왔음
import {articles} from '../../../data'
export default function handler(req, res){
res.status(200).json(articles)
}
api > article > [id]
import { articles } from '../../../data'
export default function handler({ query: { id }}, res) {
const filtered = articles.filter(article => article.id === id)
if(filtered.length > 0) {
res.status(200).json(filtered[0])
} else {
res.status(404).json({message: `Article with the id of ${id} is not found`})
}
}
config > index.js
const dev = process.env.NODE_ENV !== 'production'
export const server = dev ? 'http://localhost:3000' : 'https://whatever.com'
pages > index.js
import {server} from '../config'
...
export const getStaticProps = async () => {
const res = await fetch(`${server}/api/articles`)
const articles = await res.json()
return {
props: {
articles,
},
}
}
//export const getStaticProps ...
pages > article > [id] > index.js
data fetching 부분 수정
next/head api로 meta태그를 작성하는 방법도 있고 직접 컴포넌트를 만들어 커스텀할 수 있음
components > Meta.js
import Head from 'next/head'
const Meta = ({title, keywords, description}) => {
return (
<Head>
<각종 meta 태그들 {title} {keywords} .../>
</Head>
)
}
Meta.defaultProps = {
title: '',
keywords: '',
description: '',
}
defaultProps로 기본값 설정
그리고 Meta 컴포넌트를 Layout.js에 import해주면 됨