Static-Site Generation 정적사이트 생성
Server-Side Rendering 서버사이드 렌더링
async/await
을 사용한fetch()
API 사용으로 변경
app
폴더 사용 시 getStaticProps
, getInitialProps
, getServerSideProps
등 이전방법은 해당폴더에선 지원안됨 참고
(app
폴더는 베타버전으로 배포에서는 사용안하는 것이 권장됨)
fetch 옵션을 통해 getServerSideProps, getStaticProps 처럼 사용 가능
예시
export default funciton Home(){
const a = use(fetchData())
return <>{/* ... */} </>
}
export async function fetchData() {
const res = await fetch(`https://.../data`)
const data = await res.json()
return data
}
fetch('https://url', option)
export default async function Page() {
// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
const staticData = await fetch(`https://...`, { cache: 'force-cache' });
// This request should be refetched on every request.
// Similar to `getServerSideProps`.
const dynamicData = await fetch(`https://...`, { cache: 'no-store' });
// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
const revalidatedData = await fetch(`https://...`, {
next: { revalidate: 10 },
});
return <div>...</div>;
}
{ cache: 'force-cache' }
- 기본값으로 생략가능(getStaticProps와 유사){ cache: 'no-store' }
- 모든 요청에서 최신 데이터 받아오기 (getServerSideProps와 유사){ next: { revalidate: 10 } }
- 10초 후 새 요청오면 페이지 새로 생성 (revalidate옵션이 있는 getStaticProps와 유사)getStaticProps함수 내부에서 API 호출 생성하면 성능이 저하됨
export default function Home({ posts }) { ... }
// 서버에서 빌드 시 해당함수가 호출된다
export async function getStaticProps() {
// 외부 데이터를 받기 (file system, API, DB, etc)
// 하지만 이 함수 내부에서 호출하면 성능이 저하됨
const data = await fetch('https://.../posts')
const posts = await res.json()
// props는 빌드시 Home 컴포넌트에 전달된다
return {
props: { posts }
}
}
✅ 따라서 lib/
폴더에 파일생성해서 api경로를 분리시킨다.
// lib/load-posts.js 로 분리
export async function loadPosts() {
const res = await fetch('https://.../posts/')
const data = await res.json()
return data
}
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
export async function getStaticProps() {
const posts = await loadPosts()
return { props: { posts } }
}
페이지의 경로가 외부데이터에 따라 다를 때 사용
ex)/pages/외부데이터제목
동적 경로를 통해 getStaticProps할 때 경로 목록을 정의해줘야함
pages/**/[id].tsx
파일로 빌드시에 정적 생성할 페이지 정함
paths.params
를 getStaticProps 로 리턴해줌
params
에 빌드할 페이지를 넣어야함
pages/posts/[id].tsx 파일존재하고 /posts/123
경로면
params는 {id: "123"}
이어야 함
function Post({ post }) {
const router = useRouter()
// getStaticProps() 끝나면 실행
if (router.isFallback) {
return <div>Loading...</div>
}
// Render post...
}
// id로 동적경로 만드는 예시- posts/1652
export async function getStaticPaths() {
const res = await fetch('https://.../posts/')
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return {
paths,
fallback: true, // false or "blocking"
};
}
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via props
return { props: { post } }
}
// 블로그 글 제목으로 동적경로 생성하는 예시- /posts/nextjs-start
export async function getStaticPaths() {
const posts = getAllPosts(['slug'])
return {
paths: posts.map((post) => {
return {
params: {
slug: post.slug,
},
}
}),
fallback: false, //다른 routes는 404
}
}
export async function getServerSideProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
return {
props: { data },
}
}