1
0
Files
DiAL/src/web/components/TargetGroup.tsx
lanyuanxiaoyao 86b8cf1950 refactor: 前端性能优化 — 倒计时组件隔离、React memoization 链路
- 新建 RefreshCountdown 组件,内部持有 timer,消除 App 每秒重渲染
- TargetBoard 分组逻辑 useMemo 化,避免 targets 引用不变时重复计算
- TargetGroup 加 React.memo,阻断无效渲染
- TrendChart 加 React.memo + chartData useMemo,避免 recharts 不必要重绘
- OverviewTab 统计项去掉 Card 包裹,改用纯 CSS 实现视觉效果
- 同步更新 refresh-control 和 target-detail-drawer spec

性能提升:消除每秒全组件树重渲染,减少 DOM 节点数
2026-05-15 12:02:39 +08:00

53 lines
1.5 KiB
TypeScript

import type { PrimaryTableCol } from "tdesign-react";
import { memo } from "react";
import { Card, PrimaryTable, Space, Tag } from "tdesign-react";
import type { TargetStatus } from "../../shared/api";
interface TargetGroupProps {
columns: Array<PrimaryTableCol<TargetStatus>>;
name: string;
onTargetClick: (target: TargetStatus) => void;
targets: TargetStatus[];
}
export const TargetGroup = memo(function TargetGroup({ columns, name, onTargetClick, targets }: TargetGroupProps) {
const up = targets.filter((t) => t.latestCheck?.matched).length;
const down = targets.length - up;
const displayName = name === "default" ? "默认分组" : name;
return (
<Card
actions={
<Space size={8}>
<Tag theme="success" title="正常" variant="light">
{up}
</Tag>
<Tag theme="danger" title="异常" variant="light">
{down}
</Tag>
</Space>
}
headerBordered
title={displayName}
>
<PrimaryTable
className="clickable-table"
columns={columns}
data={targets}
defaultSort={[{ descending: true, sortBy: "latestCheck.matched" }]}
hover
onRowClick={({ row }) => onTargetClick(row)}
rowClassName={({ row }) => {
const target = row;
return target.latestCheck?.matched === false ? "row-down" : "";
}}
rowKey="id"
size="small"
stripe
/>
</Card>
);
});