0. 시작하기 전..
- 코딩앙마님의 강의를 참고하였습니다! (강의영상 바로가기)
1. 로딩 페이지 제작
- 화면이 넘어갈 때, 사용할 로딩 페이지를 만들어보겠습니다.
- #1. index.js 에 들어가 다음과 같이 입력해줍니다.
import Axios from "axios";
import Head from "next/head";
import { useEffect, useState } from "react";
import ItemList from "@/src/component/ItemList";
import styles from "@/styles/Home.module.css";
import { Divider, Header, Loader } from "semantic-ui-react";
export default function Home() {
const [list, setList] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const API_URL =
"http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline";
function getData() {
// 상품을 받아옴
Axios.get(API_URL).then((res) => {
console.log(res.data);
setList(res.data);
setIsLoading(false);
});
}
useEffect(() => {
getData();
}, []);
return (
<div>
<Head>
<title>NewBean</title>
</Head>
{isLoading && (
<div style={{ padding: "300px 0" }}>
{/* 로딩화면 추가 */}
<Loader inline="centered" active>
Loading
</Loader>
</div>
)}
{!isLoading && (
<>
<Header as="h3" style={{ paddingTop: 40 }}>
베스트 상품
</Header>
<Divider />
<ItemList list={list.slice(0, 9)} />
<Header as="h3" style={{ paddingTop: 40 }}>
신상품
</Header>
<Divider />
<ItemList list={list.slice(9)} />
</>
)}
</div>
);
}
- #2. [id].js에 들어가 다음과 같이 입력해줍니다.
import Axios from "axios";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Item from "../../src/component/Item";
import { Loader } from "semantic-ui-react";
const Post = () => {
const router = useRouter();
const { id } = router.query;
const [item, setItem] = useState({});
const [isLoading, setIsLoading] = useState(true);
const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
function getData() {
Axios.get(API_URL).then((res) => {
setItem(res.data);
setIsLoading(false);
});
}
useEffect(() => {
if (id && id > 0) {
getData();
}
}, [id]);
return (
<>
{isLoading ? (
<div style={{ padding: "300px 0" }}>
{/* 로딩화면 추가 */}
<Loader inline="centered" active>
Loading
</Loader>
</div>
) : (
<Item item={item} />
)}
</>
);
};
export default Post;
- #3. 이제 브라우저에 들어가보면, 로딩이 나오는 것을 확인할 수 있습니다.
2. 사전 렌더링 (pre-rendering)
- 웹 개발에서는 사전 렌더링(pre-rendering)이라고 있습니다.
- 사전 렌더링은 사용자가 특정 페이지로 이동하기 전, 해당 페이지의 일부 or 전체를 미리 렌더링합니다.
- 그렇게 하면 페이지 로딩 시간을 단축하고 사용자 경험을 향상시키는데 사용될 수 있습니다.
- 사전 렌더링에는 크게 정적 생성과 서버사이드 렌더링이 있습니다. 이 둘의 차이점은 언제 html 파일을 생성하는가 입니다.
- 정적 생성 (Static Generation)
- 웹 페이지의 콘텐츠를 미리 서버 측에서 생성하고 저장하는 방식을 가리킵니다.
- 프로젝트가 빌드하는 시점에 html 파일들을 생성합니다.
- 모든 요청에 파일들을 재사용합니다.
- 정적 생성된 페이지들은 CDN에 캐시됩니다.
- 퍼모먼스 이유로, Next.js는 정적 생성을 권고합니다.
- getStaticProps / getStaticPaths
- 서버사이드 렌더링 (ServerSide Rendring)
- 웹 페이지의 콘텐츠를 서버에서 동적으로 생성한 후, 클라이언트에게 제공하는 방식입니다.
- 사용자가 페이지에 접속할 때마다 서버에서 요청을 받아 html을 생성하여 전달합니다.
- 항상 최신 상태를 유지합니다.
- 각 요청마다 서버에서 동적으로 html을 생성하므로, CDN에 캐시되지 않아 느릴 수 있습니다.
- getServerSideProps
- #1. 이제 적용해봅시다! 처음 index.js에서 title태그 밑에 다음과 같이 입력해줍니다.
<meta name="description" content="NewBean 홈입니다."></meta>
- #2. [id].js 에서 다음과 같이 입력해줍니다.
→ 이렇게 하면, 검색엔진에서 상품의 내용이 검색되게끔 할 수 있습니다.
import Axios from "axios";
import Head from "next/head";
import Item from "../../src/component/Item";
const Post = ({ item }) => {
return (
<>
{item && (
<>
<Head>
<title>{item.name}</title>
<meta name="description" content={item.description}></meta>
</Head>
<Item item={item} />
</>
)}
</>
);
};
export default Post;
// 서브사이드 렌더링을 위한 코드
export async function getServerSideProps(context) {
const id = context.params.id;
const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
const res = await Axios.get(apiUrl);
const data = res.data;
return {
props: {
item: data,
},
};
}
- #3. gnb.js에 들어가서 다음과 같이 입력하여 메뉴 클릭시, 페이지 이동을 구현해봅시다.
→ 브라우저로 가서 클릭하면, 제대로 작동하는 것을 알 수 있습니다.
import { useRouter } from "next/router";
import { Menu } from "semantic-ui-react";
export default function Gnb() {
const router = useRouter();
let activeItem;
if (router.pathname === "/") {
activeItem = "home";
} else if (router.pathname === "/about") {
activeItem = "about";
}
// 버튼 클릭 시, 원하는 링크로 이동하기
function goLink(e, data) {
if(data.name === 'home') {
router.push("/");
} else if (data.name === 'about') {
router.push("/about");
}
}
return (
<Menu inverted>
<Menu.Item
name="home"
active={activeItem === "home"}
onClick={goLink}
/>
<Menu.Item
name="about"
active={activeItem === "about"}
onClick={goLink}
/>
</Menu>
);
}
- #4. view 폴더에 있는 about.js에 들어가 다음과 같이 입력하여 디자인해줍니다. (파일이 없을 시, 생성)
import {
Button,
Divider,
Form,
Header,
List,
TextArea,
} from "semantic-ui-react";
export default function about() {
return (
<div>
<Header as="h3" style={{ paddingTop: 40 }} color="teal">
회사 소개
</Header>
<Divider />
<List>
<List.Item>
<List.Icon name="users" />
<List.Content>Semantic UI</List.Content>
</List.Item>
<List.Item>
<List.Icon name="marker" />
<List.Content>New York, NY</List.Content>
</List.Item>
<List.Item>
<List.Icon name="mail" />
<List.Content>
<a href="mailto:kim@semantic-ui.com">kim@semantic-ui.com</a>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name="linkify" />
<List.Content>
<a href="http://www.semantic-ui.com">semantic-ui.com</a>
</List.Content>
</List.Item>
</List>
<Header as="h3" style={{ paddingTop: 40 }} color="teal">
문의 사항
</Header>
<Divider />
<Form>
<Form.Field>
<label>제목</label>
<input />
</Form.Field>
<Form.Field>
<label>내용</label>
<TextArea />
</Form.Field>
<Button color="green">보내기</Button>
</Form>
</div>
);
}
3. 정리하며
- 지금까지 서버사이드 렌더링에 대해 알고 로딩 페이지와 About 페이지를 작업해 보았습니다.
※ 참고 깃 주소 : https://github.com/NewBean0312/nextjs-study/commit/ae16b8603b6af9756c6d408fff18c9b917c181cf
'Front-End Study > Next.js' 카테고리의 다른 글
정적 생성 (Static Generation) (1) | 2023.12.18 |
---|---|
에러 페이지와 환경 변수 (0) | 2023.12.13 |
Dynamic Routes (0) | 2023.12.11 |
페이지 레이아웃 생성 (0) | 2023.12.01 |
Next.js 설치 (0) | 2023.12.01 |