웹: Schedule 페이지 일정/카테고리 로딩 useQuery로 리팩토링

This commit is contained in:
caadiq 2026-01-12 15:51:27 +09:00
parent 990d360520
commit d999872517
2 changed files with 35 additions and 62 deletions

View file

@ -1,7 +1,7 @@
import { useState, useEffect, useMemo, useRef, useCallback } from 'react'; import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { Clock, Tag, Link2, ChevronLeft, ChevronRight, ChevronDown, Search, X, Calendar } from 'lucide-react'; 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 { useInView } from 'react-intersection-observer';
import { useVirtualizer } from '@tanstack/react-virtual'; import { useVirtualizer } from '@tanstack/react-virtual';
import { getSchedules, getCategories, searchSchedules } from '../../../api/public/schedules'; import { getSchedules, getCategories, searchSchedules } from '../../../api/public/schedules';
@ -17,9 +17,6 @@ const decodeHtmlEntities = (text) => {
// //
function MobileSchedule() { function MobileSchedule() {
const [selectedDate, setSelectedDate] = useState(new Date()); 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 [isSearchMode, setIsSearchMode] = useState(false);
const [searchInput, setSearchInput] = useState(''); // const [searchInput, setSearchInput] = useState(''); //
const [searchTerm, setSearchTerm] = useState(''); // const [searchTerm, setSearchTerm] = useState(''); //
@ -130,23 +127,21 @@ function MobileSchedule() {
} }
}, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]); }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]);
// ( ) // (useQuery)
const viewMonth = `${selectedDate.getFullYear()}-${selectedDate.getMonth()}`; const viewYear = selectedDate.getFullYear();
const viewMonth = selectedDate.getMonth() + 1;
useEffect(() => {
const year = selectedDate.getFullYear(); //
const month = selectedDate.getMonth() + 1; const { data: categories = [] } = useQuery({
queryKey: ['scheduleCategories'],
setLoading(true); queryFn: getCategories,
Promise.all([ });
getSchedules(year, month),
getCategories() //
]).then(([schedulesData, categoriesData]) => { const { data: schedules = [], isLoading: loading } = useQuery({
setSchedules(schedulesData); queryKey: ['schedules', viewYear, viewMonth],
setCategories(categoriesData); queryFn: () => getSchedules(viewYear, viewMonth),
setLoading(false); });
}).catch(console.error);
}, [viewMonth]);
// //
const changeMonth = (delta) => { const changeMonth = (delta) => {

View file

@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useMemo, useDeferredValue, memo } from 're
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2, X } from 'lucide-react'; 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 { useVirtualizer } from '@tanstack/react-virtual';
import { useInView } from 'react-intersection-observer'; import { useInView } from 'react-intersection-observer';
import { getTodayKST } from '../../../utils/date'; import { getTodayKST } from '../../../utils/date';
@ -28,10 +28,21 @@ function Schedule() {
// //
const [schedules, setSchedules] = useState([]);
const [categories, setCategories] = useState([]);
const [selectedCategories, setSelectedCategories] = 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); const [showCategoryTooltip, setShowCategoryTooltip] = useState(false);
@ -132,39 +143,7 @@ function Schedule() {
return () => clearTimeout(timeoutId); return () => clearTimeout(timeoutId);
}, [originalSearchQuery]); }, [originalSearchQuery]);
// // / useQuery
// ()
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);
}
};
// //
useEffect(() => { useEffect(() => {
@ -195,11 +174,10 @@ function Schedule() {
}, [selectedDate]); }, [selectedDate]);
// //
const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate(); const getDaysInMonth = (y, m) => new Date(y, m + 1, 0).getDate();
const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay(); const getFirstDayOfMonth = (y, m) => new Date(y, m, 1).getDay();
const year = currentDate.getFullYear(); // year, month (useQuery)
const month = currentDate.getMonth();
const daysInMonth = getDaysInMonth(year, month); const daysInMonth = getDaysInMonth(year, month);
const firstDay = getFirstDayOfMonth(year, month); const firstDay = getFirstDayOfMonth(year, month);