728x90
Client에서 값을 받아오기에 앞서 받아온값의 상태를 확인하기위해 Reducer를 사용,처음 실핼될때 한번만 사용하기위해 Effect로 실행시키는 함수를 다른 파일에 작성하였다.
useAsync.js
import { useReducer, useEffect } from "react";
const initialState = {
loading: false,
data: null,
error: null
}
// 로딩중, 데이터 받기 성공, 데이터 받기 실패
// LOADING , SUCCESS, ERROR
function reducer(state, action){
switch(action.type){
case "LOADING":
return {
loading: true,
data: null,
error: null
};
case "SUCCESS":
return {
loading: false,
data: action.data, // 실행될때 받아온 값을 넣어줌
error: null
};
case "ERROR":
return {
loading: false,
data: null,
error: action.error
};
default:
return state;
}
}
function useAsync(callback, deps=[]){
const [state, dispatch] = useReducer(reducer, initialState);
const fetchDate = async () => {
dispatch({type:"LOADING"});
try {
const data = await callback();
dispatch({
type: "SUCCESS",
data: data
})
}
catch(e){
dispatch({
type:"ERROR",
error: e
})
}
}
useEffect(()=>{
fetchDate();
// eslint-disable-next-line
}, deps);
return [state, fetchDate];
}
export default useAsync
첫 홈 메인화면, 슬라이더는 ant.design 에서 필요한 코드를 뺴와 만들었음.
https://ant.design/components/carousel/
main / index.js
async function getProducts(){ // 서버에서 products로 요청하면 주는 값들을 가져와서 리턴해준다.
const response = await axios.get(`${API_URL}/products`)
return response.data;
}
const contentStyle = {
height: '160px',
color: '#fff',
lineHeight: '160px',
textAlign: 'center',
position:'absolute',
bottom : '50px',
};
const MainPage = () => {
const onChange = (currentSlide) => {
console.log(currentSlide);
};
// eslint-disable-next-line
const [state, refetch] = useAsync(getProducts,[]) // 값을 요청한다. useAsync파일에 있는 함수를 실행 1회만 실행을위해 빈배열을 넣어준다.
const { loading, data, error} = state;
if(loading) return <div>로딩중......</div>
if(error) return <div>에러가 발생했습니다.</div>
if(!data) return <div>로딩중입니다.</div>
return (
<div>
<div id="main">
<div id="banner">
{/* 메인 슬라이더 */}
<Carousel afterChange={onChange} autoplay>
<div>
<img src="images/banners/banner1.png" alt="" />
<h3 style={contentStyle}></h3>
</div>
<div>
<img src="images/banners/banner1.png" alt="" />
<h3 style={contentStyle}></h3>
</div>
<div>
<img src="images/banners/banner1.png" alt="" />
<h3 style={contentStyle}></h3>
</div>
</Carousel>
{/* 메인 슬라이더 / */}
</div>
<div id="product-list" className='inner'>
<h2>그린조명 최신상품</h2>
<div id="product-items">
{data.map(product=><MainProduct key={product.id} product={product}/>)}
</div>
</div>
</div>
</div>
);
};
const MainProduct = ({product}) => {
return (
<div className="product-card">
<Link to={`/product/${product.id}`}> // 클릭이벤트 삽입.
<div className='product-img'>
<img src={product.imageUrl} alt="" />
</div>
<div className='product-contents'>
<span className='product-name'>{product.name}</span>
<span className='product-price'>{product.price}</span>
<div className='product-seller'>
<img src="images/icons/avatar.png" alt="" />{product.seller}
</div>
</div>
</Link>
</div>
);
};
맵으로 돌려 값들을 모두 받아와 map으로 돌리고, Link to를 이용해 하나하나 상세페이지보기 클릭이벤트를 걸어준다.
728x90
'프론트앤드 수업' 카테고리의 다른 글
[React] Sqlite DB사용, 간단한 웹페이지 만들기_4 (0) | 2022.07.05 |
---|---|
[React] Sqlite DB사용, 간단한 웹페이지 만들기_3 (0) | 2022.07.05 |
[React] Sqlite DB사용, 간단한 웹페이지 만들기_1 (0) | 2022.07.05 |
[React] Constext 활용 (0) | 2022.06.29 |
[React] API연동 axios라이브러리 / state와 Reducer 으로 값 출력하기 (0) | 2022.06.28 |