Commit 9b60bf72e37cbebe4d6a7cdf5167fccc7d4993b3

Authored by zichun
1 parent 2900cc7c

chore(usr): FE-03 门禁回归通过 REQ-USR-003

frontend/src/pages/usr/UserList/useUserList.ts
... ... @@ -51,6 +51,9 @@ export function useUserList(): UseUserListReturn {
51 51 const messageRef = useRef(message);
52 52 messageRef.current = message;
53 53  
  54 + // 卸载守卫:避免异步取数 resolve/reject 在组件卸载后 setState(防内存泄漏 / 测试环境拆除后报错)
  55 + const mountedRef = useRef(true);
  56 +
54 57 /** 以给定 query 取数;同步 total/pageNum/pageSize 回显(BR15);错误码分流(spec § 4) */
55 58 const runFetch = useCallback(async (q: UserListQuery) => {
56 59 setQuery(q);
... ... @@ -59,6 +62,7 @@ export function useUserList(): UseUserListReturn {
59 62 setError(null);
60 63 try {
61 64 const pageData = await listUsers(q);
  65 + if (!mountedRef.current) return;
62 66 setList(pageData.records);
63 67 setTotal(pageData.total);
64 68 // 信任后端回显(越界回退最后一页等),同步分页当前页/页大小(BR15)
... ... @@ -69,6 +73,7 @@ export function useUserList(): UseUserListReturn {
69 73 });
70 74 setLoading(false);
71 75 } catch (err) {
  76 + if (!mountedRef.current) return;
72 77 const apiErr = err instanceof ApiError ? err : new ApiError(-1, TEXT_MSG_NETWORK);
73 78 setLoading(false);
74 79 if (apiErr.code === ERR_PAGE_INVALID) {
... ... @@ -92,7 +97,11 @@ export function useUserList(): UseUserListReturn {
92 97  
93 98 // 挂载即以默认条件取数(initialLoading,BR2)
94 99 useEffect(() => {
  100 + mountedRef.current = true;
95 101 void runFetch({ ...DEFAULT_QUERY });
  102 + return () => {
  103 + mountedRef.current = false;
  104 + };
96 105 // eslint-disable-next-line react-hooks/exhaustive-deps
97 106 }, []);
98 107  
... ... @@ -140,11 +149,11 @@ export function useUserList(): UseUserListReturn {
140 149 const pageData = await listUsers({ ...cur, pageNum: 1, pageSize: fetchSize });
141 150 const csv = buildUserCsv(pageData.records);
142 151 downloadCsv(EXPORT_FILENAME, csv);
143   - messageRef.current.success(TEXT_EXPORT_SUCCESS);
  152 + if (mountedRef.current) messageRef.current.success(TEXT_EXPORT_SUCCESS);
144 153 } catch {
145   - messageRef.current.error(TEXT_EXPORT_FAIL);
  154 + if (mountedRef.current) messageRef.current.error(TEXT_EXPORT_FAIL);
146 155 } finally {
147   - setExporting(false);
  156 + if (mountedRef.current) setExporting(false);
148 157 }
149 158 }, [total]);
150 159  
... ...
frontend/tests/unit/UserTable.test.tsx
1 1 // REQ-USR-003: UserTable 表格单测(BR1/BR6/BR11/BR12/BR14/D8)
2 2 import { describe, it, expect, vi, beforeEach } from 'vitest';
3   -import { screen, within } from '@testing-library/react';
  3 +import { screen } from '@testing-library/react';
4 4 import userEvent from '@testing-library/user-event';
5 5 import { renderShell } from './renderShell';
6 6 import UserTable from '../../src/pages/usr/UserList/UserTable';
... ...