<useEffect, useState 와 useSession 의 사용>
유저별 랜덤 선택기는, 기존의 랜덤 선택기와는 달리,
데이터 페치를 해온 FavoritesArray Data 안에 있는 food id 들을 사용하여,
for 과 find 를 이용하여, 다시, 모든 Data가 들어있는 FoodData 형태로 바꾸어,
데이터를 사용하는 코드가 필요했습니다.
또한, 로그인이 반드시 되어있어야 하므로, useEffect 를 사용하여,
status 가 바뀔때에, 변환을 하게 만들었습니다.
useSession 의 session Data가 필요한데, useSession 의 생명주기로 인하여, useEffect 없이
전역코드에 session 을 사용했다가는, 참조오류가 나오게 됩니다.

<주요 프로세스>
1. 음식들 ID 로, DATA 형태의 객체 배열로 변환하기
useEffect(() => {
if (status === "authenticated") {
const userFavoriteFoodArray = allFavoriteFoods.find(
(food) => food.userEmail == session.user.email
);
let favorites = [];
if (userFavoriteFoodArray) {
for (const foodid of userFavoriteFoodArray.foodArray) {
const result = allFoods.find((food) => food.id === foodid);
favorites.push(result);
}
}
setFavoritesData(favorites);
}
}, [status]);
2. 랜덤으로, 음식 선택하기
function randomSelect() {
if (favoritesData.length == 0) {
setNoData(true);
return;
} else {
randomNumber = Math.ceil(Math.random() * favoritesData.length);
setRandomFood(favoritesData[randomNumber - 1]);
setShowFood(true);
}
<코드>
// 1) Page 에서 "사전데이터페칭"으로 "모든 데이터와, 모든 Favorties 데이터"를 가져와, "컴포넌트에 넘김"
// 2) useSeesion 으로, "모든 Favorties 데이터" 에 담긴 것들 중, "유저에게 맞는 데이터만 불러와서 (find)"
// 3) 불러온 Array 로, allFoodData 를, for, find 처리해서, 값을 남긴다.
import Button from "../ui/card/button";
import FoodDetailForm from "../food-detail-components/food-detail-form";
import { useState, useEffect } from "react";
import { useSession } from "next-auth/react";
import styles from "./random-select.module.css";
function RandomSelectComponent(props) {
const { allFoods, allFavoriteFoods } = props; // page 에서 "사전데이터페칭" 으로 값을 가져옴
const { data: session, status } = useSession();
const [randomFood, setRandomFood] = useState(); // 모든 찜한 음식들의 데이터들 중,
"화면에 표시될 단 하나의 데이터"
const [favoritesData, setFavoritesData] = useState([]); // 모든 찜한 음식들의 데이터
const [showFood, setShowFood] = useState(false); // 랜덤! 버튼을 누르면 나올 모듈
const [noData, setNoData] = useState(false); // 데이터가 없다면, 나올 모듈
useEffect(() => {
if (status === "authenticated") {
const userFavoriteFoodArray = allFavoriteFoods.find(
(food) => food.userEmail == session.user.email
);
let favorites = [];
if (userFavoriteFoodArray) {
for (const foodid of userFavoriteFoodArray.foodArray) {
const result = allFoods.find((food) => food.id === foodid);
favorites.push(result);
}
}
setFavoritesData(favorites);
}
}, [status]);
let randomNumber;
function randomSelect() {
if (favoritesData.length == 0) {
setNoData(true);
return;
} else {
randomNumber = Math.ceil(Math.random() * favoritesData.length);
setRandomFood(favoritesData[randomNumber - 1]);
setShowFood(true);
}
}
return (
<div className={styles.maindiv}>
{!showFood && (
<div>
<h2> 이 음식은 어떠신가요?</h2>
<p>{session.user.email} 님의 찜한 음식 내에서 골라드립니다. </p>
</div>
)}
<Button onClick={randomSelect}> 랜덤!</Button>
{noData && <div className={styles.noSave}> 찜한 음식이 없습니다!</div>}
{showFood && (
<div>
<FoodDetailForm
id={randomFood.id}
name={randomFood.name}
image={randomFood.image}
price={randomFood.price}
taste={randomFood.taste}
category={randomFood.category}
alt={randomFood.alt}
calorie={randomFood.calorie}
nutri={randomFood.nutri}
content={randomFood.content}
/>
</div>
)}
</div>
);
}
export default RandomSelectComponent;

'메인-프로젝트 > Next.js - 오늘 뭐먹지? 프로젝트' 카테고리의 다른 글
12. Vercel 에 배포하기 (0) | 2022.12.03 |
---|---|
11. 배포 준비하기 (0) | 2022.12.03 |
9. 개인 유저 별 찜 기능을 구현해보자 (0) | 2022.12.03 |
8. 칼로리 계산기를 만들어보자. with DOM (0) | 2022.12.03 |
7. 모든 음식들을, 카테고리 별로, 태그 별로 검색되도록 구현하자 (0) | 2022.12.02 |
댓글