본문 바로가기
  • 삽질하는 자의 블로그
메인-프로젝트/Next.js - 오늘 뭐먹지? 프로젝트

10. 유저별 랜덤 선택기 구현하기

by 이게뭐당가 2022. 12. 3.

<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;

 

 

댓글