import React, { useEffect, useState, memo, useMemo, useCallback } from "react"; import { logger } from "@/utils/logger"; import BudgetTabContent from "./BudgetTabContent"; import { BudgetPeriod, BudgetData } from "@/contexts/budget/types"; interface BudgetProgressCardProps { budgetData: BudgetData; selectedTab: string; setSelectedTab: (value: string) => void; formatCurrency: (amount: number) => string; calculatePercentage: (spent: number, target: number) => number; onSaveBudget: ( type: BudgetPeriod, amount: number, newCategoryBudgets?: Record ) => void; } const BudgetProgressCard: React.FC = memo( ({ budgetData, selectedTab, setSelectedTab, formatCurrency, calculatePercentage, onSaveBudget, }) => { // 데이터 상태 추적 (불일치 감지를 위한 로컬 상태) const [_localBudgetData, setLocalBudgetData] = useState(budgetData); // 월간 예산 설정 여부 메모이제이션 const isMonthlyBudgetSet = useMemo(() => { return budgetData.monthly.targetAmount > 0; }, [budgetData.monthly.targetAmount]); // 탭 설정 콜백 메모이제이션 const handleTabSetting = useCallback(() => { if (!selectedTab || selectedTab !== "monthly") { logger.info("초기 탭 설정: monthly"); setSelectedTab("monthly"); } }, [selectedTab, setSelectedTab]); // 예산 저장 콜백 메모이제이션 const handleSaveBudget = useCallback( (amount: number, categoryBudgets?: Record) => { onSaveBudget("monthly", amount, categoryBudgets); }, [onSaveBudget] ); // budgetDataUpdated 이벤트 핸들러 메모이제이션 const handleBudgetDataUpdated = useCallback(() => { logger.info("BudgetProgressCard: 예산 데이터 업데이트 이벤트 감지"); }, []); // 컴포넌트 마운트 및 budgetData 변경 시 업데이트 useEffect(() => { logger.info( "BudgetProgressCard 데이터 업데이트 - 예산 데이터:", budgetData ); logger.info("월간 예산:", budgetData.monthly.targetAmount); setLocalBudgetData(budgetData); // 지연 작업으로 이벤트 발생 (컴포넌트 마운트 후 데이터 갱신) const timeoutId = setTimeout(() => { window.dispatchEvent(new Event("budgetDataUpdated")); }, 300); return () => clearTimeout(timeoutId); }, [budgetData]); // 초기 탭 설정을 위한 효과 useEffect(() => { handleTabSetting(); }, [handleTabSetting]); // budgetDataUpdated 이벤트 감지 useEffect(() => { window.addEventListener("budgetDataUpdated", handleBudgetDataUpdated); return () => window.removeEventListener( "budgetDataUpdated", handleBudgetDataUpdated ); }, [handleBudgetDataUpdated]); logger.info(`BudgetProgressCard 상태: 월=${isMonthlyBudgetSet}`); return (
지출 / 예산
); } ); BudgetProgressCard.displayName = "BudgetProgressCard"; export default BudgetProgressCard;