Fix: Handle undefined budget data
The `useBudgetTabContent` hook was throwing an error when `data` prop was undefined. This commit adds a check to ensure that `data` is defined before accessing its properties.
This commit is contained in:
@@ -13,7 +13,7 @@ interface BudgetData {
|
|||||||
remainingAmount: number;
|
remainingAmount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BudgetTabContentProps {
|
export interface BudgetTabContentProps {
|
||||||
data: BudgetData;
|
data: BudgetData;
|
||||||
formatCurrency: (amount: number) => string;
|
formatCurrency: (amount: number) => string;
|
||||||
calculatePercentage: (spent: number, target: number) => number;
|
calculatePercentage: (spent: number, target: number) => number;
|
||||||
@@ -26,6 +26,12 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
|
|||||||
calculatePercentage,
|
calculatePercentage,
|
||||||
onSaveBudget
|
onSaveBudget
|
||||||
}) => {
|
}) => {
|
||||||
|
// 데이터 유효성 체크 - 데이터가 없으면 기본값 사용
|
||||||
|
if (!data) {
|
||||||
|
console.warn('BudgetTabContent: data prop이 제공되지 않았습니다. 기본값을 사용합니다.');
|
||||||
|
data = { targetAmount: 0, spentAmount: 0, remainingAmount: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
categoryBudgets,
|
categoryBudgets,
|
||||||
showBudgetInput,
|
showBudgetInput,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Transaction } from '@/contexts/budget/types';
|
import { Transaction } from '@/contexts/budget/types';
|
||||||
import TransactionEditDialog from './TransactionEditDialog';
|
import TransactionEditDialog from './TransactionEditDialog';
|
||||||
@@ -8,7 +9,7 @@ import { useRecentTransactions } from '@/hooks/transactions/useRecentTransaction
|
|||||||
import { useRecentTransactionsDialog } from '@/hooks/transactions/useRecentTransactionsDialog';
|
import { useRecentTransactionsDialog } from '@/hooks/transactions/useRecentTransactionsDialog';
|
||||||
import RecentTransactionItem from './recent-transactions/RecentTransactionItem';
|
import RecentTransactionItem from './recent-transactions/RecentTransactionItem';
|
||||||
|
|
||||||
interface RecentTransactionsSectionProps {
|
export interface RecentTransactionsSectionProps {
|
||||||
transactions: Transaction[];
|
transactions: Transaction[];
|
||||||
onUpdateTransaction?: (transaction: Transaction) => void;
|
onUpdateTransaction?: (transaction: Transaction) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,15 +37,18 @@ export const useBudgetTabContent = ({
|
|||||||
calculatePercentage,
|
calculatePercentage,
|
||||||
onSaveBudget
|
onSaveBudget
|
||||||
}: UseBudgetTabContentProps): UseBudgetTabContentReturn => {
|
}: UseBudgetTabContentProps): UseBudgetTabContentReturn => {
|
||||||
|
// 데이터가 undefined인 경우를 방지하기 위한 기본값 설정
|
||||||
|
const safeData = data || { targetAmount: 0, spentAmount: 0, remainingAmount: 0 };
|
||||||
|
|
||||||
const [categoryBudgets, setCategoryBudgets] = useState<Record<string, number>>({});
|
const [categoryBudgets, setCategoryBudgets] = useState<Record<string, number>>({});
|
||||||
const [showBudgetInput, setShowBudgetInput] = useState(false);
|
const [showBudgetInput, setShowBudgetInput] = useState(false);
|
||||||
const spentAmount = data.spentAmount;
|
const spentAmount = safeData.spentAmount;
|
||||||
const targetAmount = data.targetAmount;
|
const targetAmount = safeData.targetAmount;
|
||||||
|
|
||||||
// 로그 추가 - 받은 데이터 확인
|
// 로그 추가 - 받은 데이터 확인
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(`BudgetTabContent 수신 데이터:`, data);
|
console.log(`BudgetTabContent 수신 데이터:`, safeData);
|
||||||
}, [data]);
|
}, [safeData]);
|
||||||
|
|
||||||
// 전역 예산 데이터가 변경되었을 때 로컬 상태 갱신
|
// 전역 예산 데이터가 변경되었을 때 로컬 상태 갱신
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -7,17 +7,24 @@ import RecentTransactionsSection from '@/components/RecentTransactionsSection';
|
|||||||
import Header from '@/components/Header';
|
import Header from '@/components/Header';
|
||||||
import { useBudget } from '@/contexts/budget';
|
import { useBudget } from '@/contexts/budget';
|
||||||
import SafeAreaContainer from '@/components/SafeAreaContainer';
|
import SafeAreaContainer from '@/components/SafeAreaContainer';
|
||||||
|
import { formatCurrency } from '@/utils/formatters';
|
||||||
|
|
||||||
const Index = () => {
|
const Index = () => {
|
||||||
const { transactions, budgetData } = useBudget();
|
const { transactions, budgetData, handleBudgetGoalUpdate } = useBudget();
|
||||||
|
|
||||||
// 페이지 마운트 시 데이터 로깅 (디버깅 용도)
|
// 데이터 구조 확인용 로깅
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.info('Index 페이지 마운트, 현재 데이터 상태:');
|
console.info('Index 페이지 마운트, 현재 데이터 상태:');
|
||||||
console.info('트랜잭션:', transactions.length);
|
console.info('트랜잭션 수:', transactions?.length);
|
||||||
console.info('예산 데이터:', budgetData);
|
console.info('예산 데이터:', budgetData);
|
||||||
}, [transactions, budgetData]);
|
}, [transactions, budgetData]);
|
||||||
|
|
||||||
|
// 예산 퍼센트 계산 함수
|
||||||
|
const calculatePercentage = (spent: number, target: number) => {
|
||||||
|
if (target <= 0) return 0;
|
||||||
|
return Math.min(100, Math.round((spent / target) * 100));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaContainer className="min-h-screen bg-neuro-background">
|
<SafeAreaContainer className="min-h-screen bg-neuro-background">
|
||||||
<div className="max-w-md mx-auto px-6">
|
<div className="max-w-md mx-auto px-6">
|
||||||
@@ -30,11 +37,23 @@ const Index = () => {
|
|||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<TabsContent value="budget" className="focus-visible:outline-none">
|
<TabsContent value="budget" className="focus-visible:outline-none">
|
||||||
<BudgetTabContent budgetData={budgetData.monthly} />
|
{budgetData && budgetData.monthly && (
|
||||||
|
<BudgetTabContent
|
||||||
|
data={budgetData.monthly}
|
||||||
|
formatCurrency={formatCurrency}
|
||||||
|
calculatePercentage={calculatePercentage}
|
||||||
|
onSaveBudget={(amount, categoryBudgets) =>
|
||||||
|
handleBudgetGoalUpdate('monthly', amount, categoryBudgets)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="recent" className="focus-visible:outline-none">
|
<TabsContent value="recent" className="focus-visible:outline-none">
|
||||||
<RecentTransactionsSection />
|
<RecentTransactionsSection
|
||||||
|
transactions={transactions || []}
|
||||||
|
onUpdateTransaction={transaction => console.log('트랜잭션 업데이트', transaction)}
|
||||||
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user