이번에는 useEffect를 이용해서 최초 페이지 진입 시 data를 받아오고 dynamic Route를 이용해서 상세 페이지를 간단하게 구현해본다.
pages/index.tsx
import { useEffect, useState } from 'react';
import Head from 'next/head';
import axios from 'axios';
import ItemList from '../src/components/ItemList';
interface productProps {
id: number;
name: string;
}
export default function Home() {
const [productList, setProductList] = useState<productProps[]>([]);
const API_URL = 'http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline';
async function getData() {
const { data } = await axios.get(API_URL);
setProductList(data);
}
useEffect(() => {
getData();
}, []);
return (
<>
<Head>
<title>HOME | FESeeker</title>
</Head>
<h1>home page</h1>
<ItemList productList={productList} />
</>
);
}
src/components/ItemList.tsx
import React from 'react';
import Item from './Item';
export interface ItemListObject {
id: number;
name: string;
}
interface productListProps {
productList: ItemListObject[];
}
export default function ItemList({ productList }: productListProps) {
return (
<ul>
{productList.map(product => {
return <Item key={product.id} product={product} />;
})}
</ul>
);
}
src/components/Item.tsx
import React from 'react';
import { ItemListObject } from './ItemList';
import Link from 'next/link';
interface ItemProps {
product: ItemListObject;
}
export default function Item({ product }: ItemProps) {
return (
<li>
<Link href={`/view/${product.id}`}>
<a>{product.name}</a>
</Link>
</li>
);
}
pages/view/[id].tsx
import axios from 'axios';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import ItemPage from '../../src/components/ItemPage';
export default function Post() {
const router = useRouter();
const { id } = router.query;
const [item, setItem] = useState({});
const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
async function getData() {
const { data } = await axios.get(API_URL);
console.log(data);
setItem(data);
}
useEffect(() => {
if (!id) return;
getData();
}, [id]);
return <ItemPage item={item} />;
}
상세 페이지의 경우 검색 엔진에서 검색했을 때 노출될 정보를 담고있고 싶다. 그렇다면 미리 페이지에 데이터가 있어야 한다. 정적으로 데이터가 미리 들어가있는지 확인하기 위해서는 "페이지 소스보기"를 사용하면 된다. 서버에서 미리 렌더링해서 데이터를 보내주기 위해 서버 사이드렌더링 방식을 사용한다.
아래처럼 개선해보자.
import axios from 'axios';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import ItemPage from '../../src/components/ItemPage';
export default function Post({ item }) {
return (
<>
<Head>
<title>{item.name} | FESeeker</title>
<meta name='description' content={item.description} />
</Head>
<ItemPage item={item} />;
</>
);
}
export async function getServerSideProps(context) {
const id = context.params.id;
const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
const { data } = await axios.get(API_URL);
console.log(id);
return {
props: {
item: data,
},
};
}
src/components/ItemPage.tsx
import React from 'react';
export default function ItemPage({ item }) {
return <div>{item.name}</div>;
}