카테고리는 헤더에 표시한다.
ProductList 페이지처럼 훅을 이용해 카테고리를 가져올테다.
ProductStore이다.
@singleton()
@Store()
export default class ProductsStore {
products: ProductSummary[] = [];
async fetchProducts() {
this.setProducts([]);
const { data } = await axios.get(`${apiBaseUrl}/products`);
const { products } = data;
this.setProducts(products);
}
@Action()
setProducts(products: ProductSummary[]) {
this.products = products;
}
}
CategoriesStore 이다.
@singleton()
@Store()
export default class CategoriesStore {
categories: Category[] = [];
async fetchCategories() {
this.setCategories([]);
const categories = await apiService.fetchCategories();
this.setCategories(categories);
}
@Action()
setCategories(categories: Category[]) {
this.categories = categories;
}
}
처음 ProductsStore를 만들었을땐 apiBaseUrl로 바로 axios 요청을 보낸다.
const API_BASE_URL = process.env.API_BASE_URL
|| 'https://shop-demo-apisample';
export default class ApiService {
private instance = axios.create({
baseURL: API_BASE_URL,
});
async fetchCategories(): Promise<Category[]> {
const { data } = await this.instance.get('/categories');
const { categories } = data;
return categories;
}
async fetchProducts(): Promise<ProductSummary[]> {
const { data } = await this.instance.get('/products');
const { products } = data;
return products;
}
}
export const apiService = new ApiService();
저수준에 가까운 fetch 코드를 apiService로 관심사를 분리해준 것.
useFetchProducts로 id를 받아 해당하는 상품들을 보여준다.
export default function ProductListPage() {
const [params] = useSearchParams();
const categoryId = params.get("categoryId") ?? undefined;
const { products } = useFetchProducts({ categoryId });
return (
<div>
<h2>Products</h2>
<Products products={products} />
</div>
);
}