From 5a79beadfa10b85faa5d2fc163bf261fbe764297 Mon Sep 17 00:00:00 2001 From: Joel Jeremy Marquez Date: Thu, 20 Feb 2025 16:38:03 -0800 Subject: [PATCH] Fix react-hooks/exhaustive-deps error on TransactionList.jsx (#4272) * Fix react-hooks/exhaustive-deps error on TransactionList.jsx * Release notes * Remove useLayoutEffect * Add back the useLayoutEffect --- eslint.config.mjs | 1 - .../transactions/TransactionList.jsx | 149 +++++++++++------- upcoming-release-notes/4272.md | 6 + 3 files changed, 99 insertions(+), 57 deletions(-) create mode 100644 upcoming-release-notes/4272.md diff --git a/eslint.config.mjs b/eslint.config.mjs index 96509d58c4..1396a4fce4 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -790,7 +790,6 @@ export default [ 'packages/desktop-client/src/components/sidebar/Tools.tsx', 'packages/desktop-client/src/components/sort.tsx', 'packages/desktop-client/src/components/spreadsheet/useSheetValue.ts', - 'packages/desktop-client/src/components/transactions/TransactionList.jsx', ], rules: { diff --git a/packages/desktop-client/src/components/transactions/TransactionList.jsx b/packages/desktop-client/src/components/transactions/TransactionList.jsx index 81bafe51cd..3bbf25cc32 100644 --- a/packages/desktop-client/src/components/transactions/TransactionList.jsx +++ b/packages/desktop-client/src/components/transactions/TransactionList.jsx @@ -100,59 +100,84 @@ export function TransactionList({ onMakeAsNonSplitTransactions, }) { const dispatch = useDispatch(); - const transactionsLatest = useRef(); const navigate = useNavigate(); const [learnCategories = 'true'] = useSyncedPref('learn-categories'); const isLearnCategoriesEnabled = String(learnCategories) === 'true'; + const transactionsLatest = useRef(); useLayoutEffect(() => { transactionsLatest.current = transactions; }, [transactions]); - const onAdd = useCallback(async newTransactions => { - newTransactions = realizeTempTransactions(newTransactions); + const onAdd = useCallback( + async newTransactions => { + newTransactions = realizeTempTransactions(newTransactions); - await saveDiff({ added: newTransactions }, isLearnCategoriesEnabled); - onRefetch(); - }, []); + await saveDiff({ added: newTransactions }, isLearnCategoriesEnabled); + onRefetch(); + }, + [isLearnCategoriesEnabled, onRefetch], + ); - const onSave = useCallback(async transaction => { - const changes = updateTransaction(transactionsLatest.current, transaction); - transactionsLatest.current = changes.data; + const onSave = useCallback( + async transaction => { + const changes = updateTransaction( + transactionsLatest.current, + transaction, + ); + transactionsLatest.current = changes.data; - if (changes.diff.updated.length > 0) { - const dateChanged = !!changes.diff.updated[0].date; - if (dateChanged) { - // Make sure it stays at the top of the list of transactions - // for that date - changes.diff.updated[0].sort_order = Date.now(); - await saveDiff(changes.diff, isLearnCategoriesEnabled); - onRefetch(); - } else { - onChange(changes.newTransaction, changes.data); - saveDiffAndApply( - changes.diff, - changes, - onChange, - isLearnCategoriesEnabled, - ); + if (changes.diff.updated.length > 0) { + const dateChanged = !!changes.diff.updated[0].date; + if (dateChanged) { + // Make sure it stays at the top of the list of transactions + // for that date + changes.diff.updated[0].sort_order = Date.now(); + await saveDiff(changes.diff, isLearnCategoriesEnabled); + onRefetch(); + } else { + onChange(changes.newTransaction, changes.data); + saveDiffAndApply( + changes.diff, + changes, + onChange, + isLearnCategoriesEnabled, + ); + } } - } - }, []); + }, + [isLearnCategoriesEnabled, onChange, onRefetch], + ); - const onAddSplit = useCallback(id => { - const changes = addSplitTransaction(transactionsLatest.current, id); - onChange(changes.newTransaction, changes.data); - saveDiffAndApply(changes.diff, changes, onChange, isLearnCategoriesEnabled); - return changes.diff.added[0].id; - }, []); + const onAddSplit = useCallback( + id => { + const changes = addSplitTransaction(transactionsLatest.current, id); + onChange(changes.newTransaction, changes.data); + saveDiffAndApply( + changes.diff, + changes, + onChange, + isLearnCategoriesEnabled, + ); + return changes.diff.added[0].id; + }, + [isLearnCategoriesEnabled, onChange], + ); - const onSplit = useCallback(id => { - const changes = splitTransaction(transactionsLatest.current, id); - onChange(changes.newTransaction, changes.data); - saveDiffAndApply(changes.diff, changes, onChange, isLearnCategoriesEnabled); - return changes.diff.added[0].id; - }, []); + const onSplit = useCallback( + id => { + const changes = splitTransaction(transactionsLatest.current, id); + onChange(changes.newTransaction, changes.data); + saveDiffAndApply( + changes.diff, + changes, + onChange, + isLearnCategoriesEnabled, + ); + return changes.diff.added[0].id; + }, + [isLearnCategoriesEnabled, onChange], + ); const onApplyRules = useCallback( async (transaction, updatedFieldName = null) => { @@ -193,26 +218,38 @@ export function TransactionList({ [], ); - const onManagePayees = useCallback(id => { - navigate('/payees', { state: { selectedPayee: id } }); - }); + const onManagePayees = useCallback( + id => { + navigate('/payees', { state: { selectedPayee: id } }); + }, + [navigate], + ); - const onNavigateToTransferAccount = useCallback(accountId => { - navigate(`/accounts/${accountId}`); - }); + const onNavigateToTransferAccount = useCallback( + accountId => { + navigate(`/accounts/${accountId}`); + }, + [navigate], + ); - const onNavigateToSchedule = useCallback(scheduleId => { - dispatch(pushModal('schedule-edit', { id: scheduleId })); - }); + const onNavigateToSchedule = useCallback( + scheduleId => { + dispatch(pushModal('schedule-edit', { id: scheduleId })); + }, + [dispatch], + ); - const onNotesTagClick = useCallback(tag => { - onApplyFilter({ - field: 'notes', - op: 'hasTags', - value: tag, - type: 'string', - }); - }); + const onNotesTagClick = useCallback( + tag => { + onApplyFilter({ + field: 'notes', + op: 'hasTags', + value: tag, + type: 'string', + }); + }, + [onApplyFilter], + ); return (