#TIL 47일차(랜덤 추천 기능)

앙꼬·2024년 7월 11일

부트캠프

목록 보기
46/59

구현 코드 및 설명

route.ts

import { createClient } from "@/supabase/server";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest): Promise<Response> {
  const supabase = createClient();
  const { data, error } = await supabase.from("recommend").select("*");

  if (error) throw error;

  const randomIndex = Math.floor(Math.random() * data.length);

  const randomData = data[randomIndex];

  if (!randomData) {
    return NextResponse.json({ error: "데이터 가져오기 실패" }, { status: 404 });
  }
  return NextResponse.json(randomData);
}
  • Supabase 클라이언트를 생성하고, recommend 테이블에서 모든 데이터를 선택한다.
  • 데이터는 data 변수에 저장되며, 요청 중 발생한 에러는 error 변수에 저장된다.

Random.tsx

"use client";
import { Recommend } from "@/types/type";
import { useQuery } from "@tanstack/react-query";
import Image from "next/image";
import { Report } from "notiflix";
import { useState } from "react";

export const getRandomFood = async (): Promise<Recommend> => {
  const response = await fetch("/api/recommend");
  if (!response.ok) {
    Report.failure("음식 추천에 오류가 있습니다", "잠시 후 다시 시도해주세요.", "확인");
  }
  return response.json();
};

const Random = () => {
  const { data: random, refetch } = useQuery<Recommend>({
    queryKey: ["getRandomFood"],
    queryFn: getRandomFood,
    enabled: false,
  });

  const [showFood, setShowFood] = useState(false);

  const handleClick = async () => {
    await refetch();
    setShowFood(true);
  };
  return (
    <div className="w-2/3 flex flex-col items-center mx-auto mb-[80px]">
      <h2 className="text-2xl font-bold">오늘 뭐 먹지?</h2>
      <p className="text-[16px] text-[#878787] mt-2 mb-4">클릭해보세요 메뉴를 추천해드립니다</p>
      <div className="w-full flex flex-col items-center">
        {!showFood && (
          <button className="w-1/2 py-8 text-2xl font-bold text-[#24CAFF] border rounded-md" onClick={handleClick}>
            Click!!
          </button>
        )}
        {showFood && random && (
          <div className="w-full h-full flex flex-col items-center mt-8">
            <h2 className="text-5xl font-bold text-[#24CAFF] mb-4">{random.menu}</h2>
            <div className="w-1/2 max-h-[200px] flex items-center justify-center overflow-hidden rounded-lg">
              <Image src={random.img_url} alt={random.menu} priority className="w-full h-full object-cover" />
            </div>
            <button
              className="w-1/2 py-2 text-2xl font-bold text-[#24CAFF] border rounded-md my-6"
              onClick={handleClick}
            >
              다시 하기
            </button>
          </div>
        )}
      </div>
    </div>
  );
};

export default Random;
  • getRandomFood 함수
    • 서버에서 음식 추천 데이터를 가져오는 비동기 함수이다.
    • API 요청이 성공하면 응답을 JSON 형식으로 반환하고, 실패하면 알림을 표시한다.
  • Random 컴포넌트
    • 음식을 추천하는 인터페이스를 제공한다.
    • useQuery를 사용해 getRandomFood 함수를 호출하지만, enabled: false로 설정해 처음에는 자동으로 실행되지 않도록 설정했다.
    • showFood 상태는 음식 추천 결과를 보여줄지 여부를 결정한다.
profile
프론트 개발자 꿈꾸는 중

0개의 댓글