현재 진행하고 있는 프로젝트의 메인화면이다
페이지를 구현하기 전에 먼저 머리속에서 순서를 정해보았다
1. 레시피 정보가 담긴 배열을 만든다.
API에서 받아와야 하지만 당장은 api가 없기 때문에 임시 Mock Data를 만들어 사용하자.
//Mock Data
const items = [
{
imgFile: 'https://homecuisine.co.kr/files/attach/images/140/868/087/c936189e03c496989162bf511a99b12e.JPG',
recipeName: '마라떡볶이',
NickName: '소연',
recipeDesc: '마라맛이 나는 떡볶이'
},
{
imgFile: 'https://www.sbfoods-worldwide.com/ko/recipes/qfttv70000001txe-img/9_FriedRice_L.png',
recipeName: '볶음밥',
NickName: '성오',
recipeDesc: '햄이 잔뜩 들어간 햄 맛 짱 강한 볶음밥을 원하시나요?!'
},
{
imgFile: 'https://cdn.mkhealth.co.kr/news/photo/202002/img_MKH200225001_0.jpg',
recipeName: '고구마맛탕',
NickName: '유진',
recipeDesc: '고구마맛탕 레시피입니다. 고구마 한 개면 한끼 뚝딱'
},
{
imgFile: 'https://recipe1.ezmember.co.kr/cache/recipe/2021/10/12/b93cbb9da52c5edf702f312d678979a91.jpg',
recipeName: '토마토계란볶음',
NickName: '차은우',
recipeDesc: '차은우처럼 먹으면 차은우처럼 되나요? 차은우가 픽한 요리 토.달.볶'
},
{
imgFile: 'https://recipe1.ezmember.co.kr/cache/recipe/2016/08/30/a85a01bb815660d165711089b6aea41f.jpg',
recipeName: '짜파구리',
NickName: '원영',
recipeDesc: '짜짜라짜짜 짜~파게티~'
},
{
imgFile: 'https://i.namu.wiki/i/QmCg_wtSaWqRXR5-gIBfAy36a14b7WOzSwMIu3AC7BECbdRKN1uOb22mes9px6thnhl2kXh1eKUWStoQLLX9WQ.webp',
recipeName: '김치볶음밥',
NickName: '카리나',
recipeDesc: '더이상 멘트가 생각나지 않음. 카리나는 존예 여신이다'
},
{
imgFile: 'https://recipe1.ezmember.co.kr/cache/recipe/2017/01/17/3d67642d4eddda0984123d1f7c587cf11.jpg',
recipeName: '돈가스김밥',
NickName: '소연',
recipeDesc: '요즘 돈가스 김밥 한줄이 5000원 넘나? 미친 물가..'
}
]
2. 그 다음 레시피 정보를 담을 레시피 카드 컴포넌트를 만든다
이 컴포넌트는 레시피의 이미지와 이름, 작성자를 보여주며 아이콘에 마우스를 올리면 레시피의 상세 정보를 보여주도록 구현했다.
import { useState } from 'react';
import style from '../style/recipeCard.module.css'
import { FaCircleInfo } from "react-icons/fa6";
export default function RecipeCard({item}) {
const [isHovered, setIsHovered] = useState(false); //mouse가 hover됐는지 여부를 검사하는 상태변수
return (
<div className={style.frame}>
<img src={item.imgFile} alt={`${item.recipeName}이미지`} />
{isHovered ?
<div className={style.infoDetailBox} onMouseLeave={() => setIsHovered(false)}>
<p>{item.recipeDesc}</p>
</div>
:
<div className={style.infoBox}>
<div className={style.info}>
<h1>{item.recipeName}</h1>
<p>@{item.NickName}</p>
</div>
<FaCircleInfo
size={30}
color='#ffffff87'
onMouseEnter={() => setIsHovered(true)} // 마우스가 들어왔을 때
/>
</div>
}
</div>
)
}
3. 메인페이지에서 방금 만든 레시피 컴포넌트 하나를 띄운다
export default function MainPage() {
return (
<div className={common.frame}>
<RecipeCard item={item}/>)
</div>
)
}
이렇게 하면 화면에는 하나의 첫번째 아이템만 덩그러니 떠있을 것이다.
map함수를 사용해 items를 하나하나 돌면서 여러개의 카드를 띄워야 한다.
export default function MainPage() {
return (
<div className={common.frame}>
{
items.map((item, itemIndex) =>
<RecipeCard key={itemIndex} item={item}/>
)
}
</div>
)
}
이렇게 하면 items에 들어있는 데이터가 모두 카드로 만들어져 화면에 뜨지만 내가 원하던 모양은 아니다.
내가 원하는 모양의 화면을 만들기 위해서는 배열 items 안에 있는 객체들을 3개씩 그룹화 하는 작업이 필요하다.
const getRows = (items) => {
const rows = [];
for (let i = 0; i < items.length; i += 3) {
rows.push(items.slice(i, i + 3));
}
return rows;
};
다음과 같이 slice를 사용해 배열을 3개씩 잘라 rows라는 새로운 배열로 만든다.
rows를 콘솔로 찍어보면 다음과 같이 배열이 만들어져 있는 것을 확인할 수 있다.
이제 만들어둔 getRows함수를 사용해 화면을 그려주면 된다
return (
<div className={common.frame}>
{
getRows(items).map((row, rowIndex) =>
<div key={rowIndex} className={style.rowFrame}>
{
row.map((item, itemIndex) => <RecipeCard key={itemIndex} item={item}/>)
}
</div>
)
}
</div>
)
'Framework(Library) > React' 카테고리의 다른 글
[React] 서버 액션(alpha) (0) | 2024.10.18 |
---|---|
[React] 상태관리 :: Redux와 React Query | 차이점 | 함께 사용하면 좋은 이유 (0) | 2024.09.27 |
[React Library] React Router의 개념과 사용방법 (3) | 2024.09.23 |
[React] Context란? | Context 사용방법과 예시 (1) | 2024.09.07 |
React와 Next.js의 차이와 Next.js 프로젝트 생성하기 (0) | 2024.01.22 |