fix(admin): 补全 React hooks 依赖并修复页面稳定性

- 各页面 useCallback/useMemo 依赖补全(modal/mutation/setter 等),避免闭包过期
- ECharts 使用 optionRef、MainLayout 缓存菜单转换函数、main.tsx 增加挂载点校验
- 学生同步结果改用 recordsCount 展示
This commit is contained in:
2026-08-05 21:14:08 +08:00
parent ab4765cee5
commit 1a1e90c72f
21 changed files with 439 additions and 341 deletions

View File

@@ -169,19 +169,22 @@ const MainLayout: React.FC = () => {
navigate(key);
if (usesDrawer) setDrawerOpen(false);
},
[navigate, usesDrawer],
[navigate, usesDrawer, setDrawerOpen],
);
const findSelectedKeys = (items: AppMenuItem[], pathname: string): string[] => {
for (const item of items) {
if (item.key === pathname) return [item.key];
if (item.children) {
const found = findSelectedKeys(item.children, pathname);
if (found.length > 0) return found;
const findSelectedKeys = useCallback(
(items: AppMenuItem[], pathname: string): string[] => {
for (const item of items) {
if (item.key === pathname) return [item.key];
if (item.children) {
const found = findSelectedKeys(item.children, pathname);
if (found.length > 0) return found;
}
}
}
return [pathname];
};
return [pathname];
},
[],
);
const findOpenKeys = (items: AppMenuItem[], pathname: string): string[] => {
for (const item of items) {
@@ -201,7 +204,7 @@ const MainLayout: React.FC = () => {
const selectedKeys = useMemo(
() => findSelectedKeys(menuItems, location.pathname),
[menuItems, location.pathname],
[menuItems, location.pathname, findSelectedKeys],
);
// 路径变化时同步展开的菜单(不干扰用户手动展开/收起)
useEffect(() => {
@@ -210,20 +213,20 @@ const MainLayout: React.FC = () => {
const routeOpenKeys = findOpenKeys(menuItems, location.pathname);
setOpenKeys((currentKeys) => [...new Set([...currentKeys, ...routeOpenKeys])]);
}
}, [location.pathname, menuItems]);
}, [location.pathname, menuItems, setOpenKeys]);
const handleOpenChange = useCallback((keys: string[]) => {
setOpenKeys(keys);
}, []);
}, [setOpenKeys]);
const transformToMenuItems = (items: AppMenuItem[]): any[] => {
const transformToMenuItems = useCallback((items: AppMenuItem[]): any[] => {
return items.map((item) => ({
key: item.key,
icon: item.icon ? iconMap[item.icon] : undefined,
label: item.label,
children: item.children ? transformToMenuItems(item.children) : undefined,
}));
};
}, []);
const menuContent = useMemo(
() => (
<Menu
@@ -237,7 +240,7 @@ const MainLayout: React.FC = () => {
style={{ border: 'none' }}
/>
),
[selectedKeys, openKeys, menuItems, handleMenuClick],
[selectedKeys, openKeys, menuItems, handleMenuClick, handleOpenChange, transformToMenuItems],
);
return (