Fix issue deleting transactions

Fixes an issue where deleting a transaction on the transaction history screen would cause the application to freeze.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-17 16:37:34 +00:00
parent acb9ae3d70
commit a53717c502
5 changed files with 74 additions and 48 deletions

View File

@@ -23,16 +23,9 @@ interface TransactionCardProps {
const TransactionCard: React.FC<TransactionCardProps> = ({
transaction,
onUpdate
}) => {
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
const { title, amount, date, category, type } = transaction;
const handleSaveTransaction = (updatedTransaction: Transaction) => {
if (onUpdate) {
onUpdate(updatedTransaction);
}
};
const { title, amount, date, category } = transaction;
return (
<>
@@ -54,7 +47,6 @@ const TransactionCard: React.FC<TransactionCardProps> = ({
transaction={transaction}
open={isEditDialogOpen}
onOpenChange={setIsEditDialogOpen}
onSave={handleSaveTransaction}
/>
</>
);

View File

@@ -10,7 +10,8 @@ import {
DialogHeader,
DialogTitle,
DialogFooter,
DialogClose
DialogClose,
DialogDescription
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Form } from '@/components/ui/form';
@@ -78,6 +79,11 @@ const TransactionEditDialog: React.FC<TransactionEditDialogProps> = ({
};
const handleDelete = () => {
// 다이얼로그 닫기를 먼저 수행 (UI 블로킹 방지)
onOpenChange(false);
// 약간의 지연 후 삭제 작업 수행 (안정성 향상)
setTimeout(() => {
// 컨텍스트를 통해 트랜잭션 삭제
deleteTransaction(transaction.id);
@@ -85,13 +91,7 @@ const TransactionEditDialog: React.FC<TransactionEditDialogProps> = ({
if (onDelete) {
onDelete(transaction.id);
}
onOpenChange(false);
toast({
title: "지출이 삭제되었습니다",
description: `${transaction.title} 항목이 삭제되었습니다.`,
});
}, 100);
};
return (
@@ -99,6 +99,9 @@ const TransactionEditDialog: React.FC<TransactionEditDialogProps> = ({
<DialogContent className={`sm:max-w-md mx-auto ${isMobile ? 'rounded-xl overflow-hidden' : ''}`}>
<DialogHeader>
<DialogTitle> </DialogTitle>
<DialogDescription>
.
</DialogDescription>
</DialogHeader>
<Form {...form}>

View File

@@ -1,3 +1,4 @@
import { useState, useEffect, useCallback } from 'react';
import { Transaction } from '../types';
import {
@@ -11,6 +12,7 @@ import { toast } from '@/hooks/useToast.wrapper'; // 래퍼 사용
export const useTransactionState = () => {
const [transactions, setTransactions] = useState<Transaction[]>([]);
const [lastDeletedId, setLastDeletedId] = useState<string | null>(null);
const [isDeleting, setIsDeleting] = useState(false);
// 초기 트랜잭션 로드 및 이벤트 리스너 설정
useEffect(() => {
@@ -72,9 +74,15 @@ export const useTransactionState = () => {
});
}, []);
// 트랜잭션 삭제 함수
// 트랜잭션 삭제 함수 - 안정성 개선
const deleteTransaction = useCallback((transactionId: string) => {
console.log('트랜잭션 삭제:', transactionId);
// 이미 삭제 중이면 중복 삭제 방지
if (isDeleting) {
console.log('이미 삭제 작업이 진행 중입니다.');
return;
}
console.log('트랜잭션 삭제 시작:', transactionId);
// 중복 삭제 방지
if (lastDeletedId === transactionId) {
@@ -82,13 +90,28 @@ export const useTransactionState = () => {
return;
}
setIsDeleting(true);
setLastDeletedId(transactionId);
try {
setTransactions(prev => {
// 기존 트랜잭션 목록 백업 (문제 발생 시 복원용)
const originalTransactions = [...prev];
// 삭제할 항목 필터링
const updated = prev.filter(transaction => transaction.id !== transactionId);
// 항목이 실제로 삭제되었는지 확인
if (updated.length === originalTransactions.length) {
console.log('삭제할 트랜잭션을 찾을 수 없음:', transactionId);
setIsDeleting(false);
return originalTransactions;
}
// 저장소에 업데이트된 목록 저장
saveTransactionsToStorage(updated);
// 토스트는 한 번만 호출
// 토스트 메시지 표시
toast({
title: "지출이 삭제되었습니다",
description: "지출 항목이 성공적으로 삭제되었습니다.",
@@ -96,10 +119,21 @@ export const useTransactionState = () => {
return updated;
});
// 5초 후 lastDeletedId 초기화
setTimeout(() => setLastDeletedId(null), 5000);
}, [lastDeletedId]);
} catch (error) {
console.error('트랜잭션 삭제 중 오류 발생:', error);
toast({
title: "삭제 실패",
description: "지출 항목 삭제 중 오류가 발생했습니다.",
variant: "destructive"
});
} finally {
// 삭제 상태 초기화 (1초 후)
setTimeout(() => {
setIsDeleting(false);
setLastDeletedId(null);
}, 1000);
}
}, [lastDeletedId, isDeleting]);
// 트랜잭션 초기화 함수
const resetTransactions = useCallback(() => {

View File

@@ -66,6 +66,7 @@ export const useTransactionsCore = () => {
// 데이터 강제 새로고침
const refreshTransactions = useCallback(() => {
console.log('트랜잭션 강제 새로고침');
setRefreshKey(prev => prev + 1);
loadTransactions();
}, [loadTransactions, setRefreshKey]);

View File

@@ -17,8 +17,7 @@ const Transactions = () => {
setSearchQuery,
handlePrevMonth,
handleNextMonth,
updateTransaction,
deleteTransaction,
refreshTransactions,
totalExpenses,
} = useTransactions();
@@ -48,15 +47,13 @@ const Transactions = () => {
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
console.log('거래내역 페이지 보임 - 데이터 새로고침');
// 상태 업데이트 트리거
setIsDataLoaded(prev => !prev);
refreshTransactions();
}
};
const handleFocus = () => {
console.log('거래내역 페이지 포커스 - 데이터 새로고침');
// 상태 업데이트 트리거
setIsDataLoaded(prev => !prev);
refreshTransactions();
};
document.addEventListener('visibilitychange', handleVisibilityChange);
@@ -66,7 +63,7 @@ const Transactions = () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
window.removeEventListener('focus', handleFocus);
};
}, []);
}, [refreshTransactions]);
return (
<div className="min-h-screen bg-neuro-background pb-24">
@@ -169,7 +166,6 @@ const Transactions = () => {
<TransactionCard
key={transaction.id}
transaction={transaction}
onUpdate={updateTransaction}
/>
))}
</div>