프리렌더링
단순한 의미로는 ~~ 이전에 하는 렌더링
- -> 웹페이지 로딩 이전에 하는 렌더링
- 프리렌더링이 실행되는 시점은?
- 웹브라우저가 html 코드를 받아오기 전에 렌더링
- 프리렌더링의 장점
- 초기 로딩이 빨리진다
-> html이 렌더링된 상태로 제공되기 때문에
- 검색엔진 최적화
-> 비어있는 html이 아니라 렌더링된 html을 미리 받기 때문에
- 프리렌더링의 2가지 방식
1. 정적 생성
2. 서버사이드 렌더링
1. 정적 생성
- 빌드를 하는 시점에 렌더링을 하는 것 (빌드할 때 html을 만드는것)
- 빌드는 배포하기 전에 소스코드를 실행할 수 있는 형태로 바꿔놓는 것 - 소스코드를 빌드하면서 파일로 미리 만들어둠
-> 웹브라우저로 접속하면 만들어 놓은 걸 그대로 보여줌
-> 렌더링 된 상태에서 자바스크립트 파일을 로딩
-> 리액트 실행 -> 기존에 화면에 렌더링 된 것들이랑 리액트랑 연결
-> 클라이언트 사이드에서 리액트가 화면 조절 - 이미 렌더링 된 htrml과 리액트의 데이터를 연결하는 작업을 Hydration이라고 부름
- build된 next 폴더의 pages -> index.html 파일에서 Format Document를 실행하면 리액트로 작성한 페이지가 html로 렌더링 된다.
- 최신 목록을 보여주는 자주 바뀌는 데이터는 정적생성이 적절하지 않다.
- 정적 생성을 도와주는 함수
getStaticProps
- 정적 생성할 때 필요한 데이터를 렌더링 하고 싶을 때, 객체의 props프로퍼티로 넘겨줄 props 객체를 지정하고 페이지 컴포넌트에서 사용할 수 있다.
- context 파라미터를 사용해서 필요한 params 값이나 쿼리스트링 값을 참조할 수있다.
getStaticPath
- 다이나믹 라우팅을 하는 페이지를 정적 생성을 할 때, 리턴값으로 객체를 리턴하는데 paths라는 배열에서 각 페이지에 해당하는 정보를 넘겨줄 수 있다.
- fallback 속성을 사용해 정적 생성되지 않은 페이지를 처리해 줄 것인지 지정할 수 있고 fallback : true로 하면 생성되지 않은 페이지로 접속했을 때 getStaticProps 함수를 실행해 페이지를 만들어서 보여준다.
- fallback: true로 지정했으면 {notFound : true} 를 리턴해 데이터를 찾을 수 없을 때 404 페이지로 이동시킬 수 있다 .
- 정적 생성을 하면서 데이터를 가져와서 사용하고 싶을 경우
export const getStaticProps = async () => {
const res = await axios.get("/products");
const products = res.data.results;
return {
props: { products },
};
};
export default function Home({ products }) {
return (
<>
<Head>
<title>DdiShop</title>
</Head>
<SearchForm />
<ProductList className={styles.products} products={products} />
</>
);
}
1. getStaticProps 함수를 만들고 리턴값으로 props값을 만듦
2. props는 페이지 컴포넌트에서 가져와서 사용하면 된다.
- 다이나믹한 페이지를 정적 생성하고 싶을 때
//다이나믹한 페이지를 정적 생성할 때 어떤 페이지를 생성할 지 정해주는 용도
export const getStaticPaths = async () => {
return{
// params id값으로 각 상품의 id를 넣어준것 , 문자열 형태로 써야함
paths:[
{params: {id: "1"}},
{params: {id: "2"}},
],
fallback: false,
}
};
export const getStaticProps = async (context) => {
// 파라미터로 받는 context 객체에서 params 값을 받아올 수 있다.
const productId = context.params["id"]; //
const res = await axios.get(`/products/${targetId}`);
const product = res.data;
return {
props: { product },
};
};
export default function Product({ product }) {
const [sizeReviews, setSizeReviews] = useState([]);
const router = useRouter();
const { id } = router.query;
async function getSizeReviews(targetId) {
const res = await axios.get(`/size_reviews/?product_id=${targetId}`);
const nextSizeReviews = res.data.results ?? [];
setSizeReviews(nextSizeReviews);
}
useEffect(() => {
if (!id) return;
getSizeReviews(id);
}, [id]);
- 이상한 상품의 id로 들어갔을 때 에러가 나는 경우에는 try, catch문을 사용해서 에러 잡기
- fallback속성을 사용하면 그때 그때 getStaticProps를 실행해서 미리 정적생성하지 않은 페이지를 보여줄 수 있다.
-데이터 없이 보여줄 로딩화면구현 -> 리퀘스트를 했을 때 데이터가 없는 경우에는 404 페이지를 보여주도록 설정
//다이나믹한 페이지를 정적 생성할 때 어떤 페이지를 생성할 지 정해주는 용도
export const getStaticPaths = async () => {
const res = await axios.get("/products");
const products = res.data.results;
const paths = products.map((product) => ({
//params id값으로 각 상품의 id를 넣어준것 , 문자열 형태로 써야함
params: { id: String(product.id) },
}))
return{
paths,
// 없는 경로에 대한 처리 방법을 정해주는 것,false=없는 페이지는 404 에러를 띄움
// true =정적생성 해놓지 않은 경로로 왔을 때(params: { id: String(product.id) }, 외에)
// getStaticProps 를 실행해서 정적 생성을 한다는 의미
fallback: true,
}
};
export const getStaticProps = async (context) => {
// 파라미터로 받는 context 객체에서 params 값을 받아올 수 있다.
const productId = context.params["id"];
let product;
try{
const res = await axios.get(`/products/${productId}`);
product = res.data;
} catch{
return { // 에러가 발생하면 404 에러를 띄움
notFound: true,
};
}
return {
props: { product },
};
};
// 페이지 컴포넌트는 내려준 props를 기준으로 렌더링함
export default function Product({ product }) {
const [sizeReviews, setSizeReviews] = useState([]);
const router = useRouter();
const { id } = router.query;
async function getSizeReviews(targetId) {
const res = await axios.get(`/size_reviews/?product_id=${targetId}`);
const nextSizeReviews = res.data.results ?? [];
setSizeReviews(nextSizeReviews);
}
useEffect(() => {
if (!id) return;
getSizeReviews(id);
}, [id]);
if (!product) return(
<div>상품 정보를 불러오는 중입니다...
</div>
);
2. 서버사이드 렌더링
- 렌더링 된 html을 보여주는데 정적 생성이랑 다른 점은
- 웹브라우저가 리퀘스트를 보낼 때마다 서버가 매번 렌더링해서 보내주는 것 - 서버사이드 렌더링도 정적 생성이랑 비슷함
export const getServerSideProps = async (context) => {
// context 객체를 파라미터로 받아서
const q = context.query["q"];
// 쿼리스트링을 가져옴
const res = await axios.get(`/products/?q=${q}`);
// 해당 쿼리스트링을 가진 상품을 가져옴
const products = res.data.results ?? [];
// 가져온 상품을 변수에 담음
return {
props: {
products,
q,
},
};
};
export default function Search({ q, products }) {
return (
<div>
<Head>
<title>{q} 검색 결과</title>
</Head>
<SearchForm initialValue={q} />
<h2 className={styles.title}>
<span className={styles.keyword}>{q}</span> 검색 결과
</h2>
<ProductList className={styles.productList} products={products} />
</div>
);
getServerSideProps 함수를 사용,
- 들어오는 리퀘스트에 따라서 다르게 프리렌더링 하거나
- 자주 바뀌는 데이터를 프리렌더링 하고 싶을 때 사용
- getStaticProps 와 getServerSideProps 는 같이 사용하면 안된다.
'넥스트 제이에스' 카테고리의 다른 글
mongoDB였던것 (0) | 2024.02.26 |
---|---|
next.js공부중 (0) | 2024.02.14 |