구현 코드 및 설명
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 상태는 음식 추천 결과를 보여줄지 여부를 결정한다.