이렇게 카테고리를 만들었는데
특정 카테고리를 클릭 했을때는 카테고리에 맞는 상품만 가져와야한다.
CardList 컴포넌트가 카테고리 선택에 따라 적절한 제품 목록을 요청하고 렌더링하는 방식이다.
1. CardList 컴포넌트에서 Redux 상태 가져오기
import React, { useEffect } from 'react'
import { useAppDispatch, useAppSelector } from '../../../hooks/redux'
import CardItem from '../card-list/card-item/CardItem'
import styles from '../card-list/CardList.module.scss'
import { fetchProducts } from '../../../store/products/products.slice'
const CardList = () => {
const dispatch = useAppDispatch();
const {products} = useAppSelector((state) => state.products);
⭐ const category = useAppSelector(state => state.category);
useEffect(()=>{
console.log("Fetching products...");
⭐ dispatch(fetchProducts( category?.toLowerCase()));
},[category])
return (
<ul className={styles.card_list}>
{products.map((item, index) => <CardItem key={index} item={item} />)}
</ul>
)
}
export default CardList
- category는 useAppSelector(state => state.category)를 통해 가져온다.
- useEffect 훅을 사용해 category가 변경될 때마다 fetchProducts 액션을 디스패치합니다.
- category가 바뀔 때마다 fetchProducts가 호출된다.
- category가 없으면 fetchProducts는 전체 제품을 요청하고, category가 있으면 해당 카테고리의 제품을 요청합니다.
2. products.slice.js 카테고리 따른 api요청
export const fetchProducts = createAsyncThunk(
"products/fetchProducts",
async (category, thunkAPI) =>{
console.log(thunkAPI);
try{
let response;
if(category){
}else{
}
return response.data ;//payload
}catch(error){
return thunkAPI.rejectWithValue("Error loading products 데이터요청 중 에러")
}
}
);
createAsyncThunk로 카테고리에 따른 API 요청 처리
- 카테고리(category)에 따라 조건적으로 API 요청을 다르게 합니다.
- category가 있으면 https://fakestoreapi.com/products/category/${category}로 요청하여 특정 카테고리 제품만 가져오고, 없으면 전체 제품을 가져옵니다.
스켈레톤 UI
1. CardSkeleton 컴포넌트 생성
import React from 'react'
import styles from "./CardSkeleton.module.scss";
import "react-loading-skeleton/dist/skeleton.css";
import Skeleton from 'react-loading-skeleton';
const CardSkeleton = () => {
return (
<div className={styles.card_skeleton_container}>
<div className={styles.card_skeleton}>
<Skeleton height={350}/>
</div>
<div className={styles.card_skeleton}>
<Skeleton height={350}/>
</div>
<div className={styles.card_skeleton}>
<Skeleton height={350}/>
</div>
<div className={styles.card_skeleton}>
<Skeleton height={350}/>
</div>
</div>
)
}
export default CardSkeleton
- Skeleton 컴포넌트는 react-loading-skeleton 라이브러리에서 제공하는 것으로, 로딩 중임을 나타내는 애니메이션을 자동으로 적용해줍니다.
2. CardList 컴포넌트에서 적용
import React, { useEffect } from 'react'
import { useAppDispatch, useAppSelector } from '../../../hooks/redux'
import CardItem from '../card-list/card-item/CardItem'
import styles from '../card-list/CardList.module.scss'
import { fetchProducts } from '../../../store/products/products.slice'
import CardSkeleton from '../card-skeleton/CardSkeleton'
const CardList = () => {
const dispatch = useAppDispatch();
⭐const {products, isLoading } = useAppSelector((state) => state.products);
const category = useAppSelector(state => state.category);
useEffect(()=>{
console.log("Fetching products...");
dispatch(fetchProducts( category?.toLowerCase()));
},[category])
if(isLoading) ⭐
return <CardSkeleton/>;
return (
<ul className={styles.card_list}>
{products.map((item, index) => <CardItem key={index} item={item} />)}
</ul>
)
}
export default CardList
- CardList 컴포넌트에서는 제품 데이터를 Redux로부터 가져와 렌더링합니다.
- 데이터를 요청할 때 로딩 상태(isLoading)가 true로 설정되며, 이 상태가 true일 경우 CardSkeleton 컴포넌트를 대신 렌더링합니다.
'⛲ 프로젝트 > 👖gproro-shop-app' 카테고리의 다른 글
[ gproro-shop-app] 로그인여부로 분기처리 with redux (0) | 2024.11.14 |
---|---|
[gproro-shop-app] 장바구니 기능 with Redux (0) | 2024.11.14 |
[gproro-shop-app] product 데이터가져오기 with Redux thunk (0) | 2024.11.12 |
[gproro-shop-app] category 컴포넌트 구현 with Redux (1) | 2024.11.12 |
[gproro-shop-app]리덕스로 로그인 , 회원가입 준비하기 (0) | 2024.11.12 |