fix(admin-web): 修复 React hooks 规则违规问题

- 将所有 useCallback hooks 移动到条件返回之前
- React 要求所有 hooks 必须在任何条件返回之前调用
- 解决客户端异常 "a client-side exception has occurred" 错误

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-07 06:13:09 -08:00
parent 603f41f9ca
commit 38fa1f807d
1 changed files with 27 additions and 27 deletions

View File

@ -300,11 +300,37 @@ export default function SystemAccountsTab() {
* [2026-01-07]
*/
function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fixedAccounts'] }) {
// [2026-01-07] 新增选中账户和分类账数据hooks 必须在条件返回之前)
// [2026-01-07] 所有 hooks 必须在条件返回之前调用
const [selectedAccount, setSelectedAccount] = useState<string | null>(null);
const [allLedgerData, setAllLedgerData] = useState<AllSystemAccountsLedgerResponse | null>(null);
const [ledgerLoading, setLedgerLoading] = useState(false);
// 加载所有固定账户的分类账明细useCallback 必须在条件返回之前)
const loadAllLedger = useCallback(async () => {
if (allLedgerData) return; // 已加载过,不重复加载
setLedgerLoading(true);
try {
const response = await systemAccountReportService.getAllLedger({ pageSize: 100 });
if (response.data) {
setAllLedgerData(response.data);
}
} catch (err) {
console.error('Failed to load ledger data:', err);
} finally {
setLedgerLoading(false);
}
}, [allLedgerData]);
// 获取指定账户的分类账数据
const getAccountLedger = useCallback((accountSequence: string): LedgerEntryDTO[] => {
if (!allLedgerData?.fixedAccountsLedger) return [];
const accountLedger = allLedgerData.fixedAccountsLedger.find(
(item) => item.accountSequence === accountSequence
);
return accountLedger?.ledger || [];
}, [allLedgerData]);
// [2026-01-07] 修复:添加空值检查,防止 data 为 undefined 时报错
if (!data) {
return <div className={styles.empty}>...</div>;
@ -325,23 +351,6 @@ function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fix
sequence: item.data?.accountSequence || '',
}));
// 加载所有固定账户的分类账明细
const loadAllLedger = useCallback(async () => {
if (allLedgerData) return; // 已加载过,不重复加载
setLedgerLoading(true);
try {
const response = await systemAccountReportService.getAllLedger({ pageSize: 100 });
if (response.data) {
setAllLedgerData(response.data);
}
} catch (err) {
console.error('Failed to load ledger data:', err);
} finally {
setLedgerLoading(false);
}
}, [allLedgerData]);
// 选择账户查看明细
const handleSelectAccount = async (accountSequence: string) => {
if (selectedAccount === accountSequence) {
@ -356,15 +365,6 @@ function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fix
setSelectedAccount(accountSequence);
};
// 获取指定账户的分类账数据
const getAccountLedger = (accountSequence: string): LedgerEntryDTO[] => {
if (!allLedgerData?.fixedAccountsLedger) return [];
const accountLedger = allLedgerData.fixedAccountsLedger.find(
(item) => item.accountSequence === accountSequence
);
return accountLedger?.ledger || [];
};
// 当前选中账户的明细数据
const currentLedger = selectedAccount ? getAccountLedger(selectedAccount) : [];