diff --git a/frontend/src/pages/mobile/public/Schedule.jsx b/frontend/src/pages/mobile/public/Schedule.jsx index 0a4ca44..839517e 100644 --- a/frontend/src/pages/mobile/public/Schedule.jsx +++ b/frontend/src/pages/mobile/public/Schedule.jsx @@ -1,7 +1,7 @@ import { useState, useEffect, useMemo, useRef, useCallback } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Clock, Tag, Link2, ChevronLeft, ChevronRight, ChevronDown, Search, X, Calendar } from 'lucide-react'; -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; import { useInView } from 'react-intersection-observer'; import { useVirtualizer } from '@tanstack/react-virtual'; import { getSchedules, getCategories, searchSchedules } from '../../../api/public/schedules'; @@ -17,9 +17,6 @@ const decodeHtmlEntities = (text) => { // 모바일 일정 페이지 function MobileSchedule() { const [selectedDate, setSelectedDate] = useState(new Date()); - const [schedules, setSchedules] = useState([]); - const [categories, setCategories] = useState([]); - const [loading, setLoading] = useState(true); const [isSearchMode, setIsSearchMode] = useState(false); const [searchInput, setSearchInput] = useState(''); // 입력값 const [searchTerm, setSearchTerm] = useState(''); // 실제 검색어 @@ -130,23 +127,21 @@ function MobileSchedule() { } }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]); - // 일정 및 카테고리 로드 (월이 변경될 때만 실행) - const viewMonth = `${selectedDate.getFullYear()}-${selectedDate.getMonth()}`; - - useEffect(() => { - const year = selectedDate.getFullYear(); - const month = selectedDate.getMonth() + 1; - - setLoading(true); - Promise.all([ - getSchedules(year, month), - getCategories() - ]).then(([schedulesData, categoriesData]) => { - setSchedules(schedulesData); - setCategories(categoriesData); - setLoading(false); - }).catch(console.error); - }, [viewMonth]); + // 일정 및 카테고리 로드 (useQuery) + const viewYear = selectedDate.getFullYear(); + const viewMonth = selectedDate.getMonth() + 1; + + // 카테고리 데이터 로드 + const { data: categories = [] } = useQuery({ + queryKey: ['scheduleCategories'], + queryFn: getCategories, + }); + + // 월별 일정 데이터 로드 + const { data: schedules = [], isLoading: loading } = useQuery({ + queryKey: ['schedules', viewYear, viewMonth], + queryFn: () => getSchedules(viewYear, viewMonth), + }); // 월 변경 const changeMonth = (delta) => { diff --git a/frontend/src/pages/pc/public/Schedule.jsx b/frontend/src/pages/pc/public/Schedule.jsx index 46dcdd1..e5a2c54 100644 --- a/frontend/src/pages/pc/public/Schedule.jsx +++ b/frontend/src/pages/pc/public/Schedule.jsx @@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useMemo, useDeferredValue, memo } from 're import { useNavigate } from 'react-router-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2, X } from 'lucide-react'; -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; import { useVirtualizer } from '@tanstack/react-virtual'; import { useInView } from 'react-intersection-observer'; import { getTodayKST } from '../../../utils/date'; @@ -28,10 +28,21 @@ function Schedule() { // 데이터 상태 - const [schedules, setSchedules] = useState([]); - const [categories, setCategories] = useState([]); const [selectedCategories, setSelectedCategories] = useState([]); - const [loading, setLoading] = useState(true); + + // 카테고리 데이터 로드 (useQuery) + const { data: categories = [] } = useQuery({ + queryKey: ['scheduleCategories'], + queryFn: getCategories, + }); + + // 월별 일정 데이터 로드 (useQuery) + const year = currentDate.getFullYear(); + const month = currentDate.getMonth(); + const { data: schedules = [], isLoading: loading } = useQuery({ + queryKey: ['schedules', year, month + 1], + queryFn: () => getSchedules(year, month + 1), + }); // 카테고리 필터 툴팁 const [showCategoryTooltip, setShowCategoryTooltip] = useState(false); @@ -132,39 +143,7 @@ function Schedule() { return () => clearTimeout(timeoutId); }, [originalSearchQuery]); - // 데이터 로드 - // 초기 데이터 로드 (카테고리만) - useEffect(() => { - loadCategories(); - }, []); - - // 월 변경 시 일정 로드 - useEffect(() => { - const year = currentDate.getFullYear(); - const month = currentDate.getMonth(); - loadSchedules(year, month + 1); - }, [currentDate]); - - const loadSchedules = async (year, month) => { - setLoading(true); - try { - const data = await getSchedules(year, month); - setSchedules(data); - } catch (error) { - console.error('일정 로드 오류:', error); - } finally { - setLoading(false); - } - }; - - const loadCategories = async () => { - try { - const data = await getCategories(); - setCategories(data); - } catch (error) { - console.error('카테고리 로드 오류:', error); - } - }; + // 카테고리/일정 데이터는 상단에서 useQuery로 관리됨 // 외부 클릭시 팝업 닫기 useEffect(() => { @@ -195,11 +174,10 @@ function Schedule() { }, [selectedDate]); // 달력 관련 함수 - const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate(); - const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay(); + const getDaysInMonth = (y, m) => new Date(y, m + 1, 0).getDate(); + const getFirstDayOfMonth = (y, m) => new Date(y, m, 1).getDay(); - const year = currentDate.getFullYear(); - const month = currentDate.getMonth(); + // year, month는 상단에서 이미 선언됨 (useQuery) const daysInMonth = getDaysInMonth(year, month); const firstDay = getFirstDayOfMonth(year, month);