refactor(web): 16 个列表页 columns 定义 useMemo 化 — 减少 Table 不必要 re-render
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

- AiPromptList/AiAnalysisList/AppointmentList 等 14 个主页面
- HealthRecordsTab/LabReportsTab 2 个 Tab 组件
- 每个 columns 依赖数组包含其引用的闭包变量(handleDelete/navigate 等)
This commit is contained in:
iven
2026-04-28 19:45:14 +08:00
parent e76f4feb4f
commit 99093d8143
16 changed files with 48 additions and 48 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import { Table, Select, Tag, Space, message, Typography } from 'antd';
import { useThemeMode } from '../../hooks/useThemeMode';
import { analysisApi, type AnalysisItem } from '../../api/ai/analysis';
@@ -69,7 +69,7 @@ export default function AiAnalysisList() {
}
};
const columns = [
const columns = useMemo(() => [
{
title: '分析类型',
dataIndex: 'analysis_type',
@@ -112,7 +112,7 @@ export default function AiAnalysisList() {
width: 170,
render: (v: string) => (v ? new Date(v).toLocaleString('zh-CN') : '-'),
},
];
], []);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -92,7 +92,7 @@ export default function AiPromptList() {
}
};
const columns = [
const columns = useMemo(() => [
{
title: '名称',
dataIndex: 'name',
@@ -161,7 +161,7 @@ export default function AiPromptList() {
</AuthButton>
),
},
];
], [handleActivate, handleRollback]);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useState, useCallback, useEffect } from 'react';
import { useState, useCallback, useEffect, useMemo } from 'react';
import {
Table,
Button,
@@ -269,7 +269,7 @@ export default function AppointmentList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '患者',
dataIndex: 'patient_name',
@@ -362,7 +362,7 @@ export default function AppointmentList() {
);
},
},
];
], [handleStatusChange]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -128,7 +128,7 @@ export default function ArticleCategoryManage() {
.filter((c) => !editingCategory || c.id !== editingCategory.id)
.map((c) => ({ label: c.name, value: c.id }));
const columns = [
const columns = useMemo(() => [
{
title: '分类名称',
dataIndex: 'name',
@@ -194,7 +194,7 @@ export default function ArticleCategoryManage() {
</AuthButton>
),
},
];
], [isDark, categories, openEditModal, handleDelete]);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Table,
@@ -242,7 +242,7 @@ export default function ArticleManageList() {
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '标题',
dataIndex: 'title',
@@ -351,7 +351,7 @@ export default function ArticleManageList() {
width: 200,
render: (_: unknown, record: ArticleListItem) => renderActions(record),
},
];
], [navigate, renderActions]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -94,7 +94,7 @@ export default function ArticleTagManage() {
}
};
const columns = [
const columns = useMemo(() => [
{
title: '标签名称',
dataIndex: 'name',
@@ -165,7 +165,7 @@ export default function ArticleTagManage() {
</AuthButton>
),
},
];
], [isDark, openEditModal, handleDelete]);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useState, useCallback, useRef } from 'react';
import { useState, useCallback, useRef, useMemo } from 'react';
import {
Table,
Button,
@@ -199,7 +199,7 @@ export default function DoctorList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '姓名',
dataIndex: 'name',
@@ -295,7 +295,7 @@ export default function DoctorList() {
</AuthButton>
),
},
];
], [openEdit, handleDelete]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -202,7 +202,7 @@ export default function DoctorSchedule() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '日期',
dataIndex: 'schedule_date',
@@ -273,7 +273,7 @@ export default function DoctorSchedule() {
</AuthButton>
),
},
];
], [openEdit]);
// ---- 将日历数据转换为 CalendarView 所需格式 ----
const calendarScheduleMap: Record<string, ScheduleItem[]> = {};

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -166,7 +166,7 @@ export default function OfflineEventList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '活动名称',
dataIndex: 'title',
@@ -279,7 +279,7 @@ export default function OfflineEventList() {
</AuthButton>
),
},
];
], [openEdit, handleCheckin, handleDelete]);
return (
<Card>

View File

@@ -1,4 +1,4 @@
import { useState, useCallback, useRef } from 'react';
import { useState, useCallback, useRef, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Table,
@@ -184,7 +184,7 @@ export default function PatientList() {
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '姓名',
dataIndex: 'name',
@@ -298,7 +298,7 @@ export default function PatientList() {
</AuthButton>
),
},
];
], [openEditModal, handleDelete]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -86,7 +86,7 @@ export default function PatientTagManage() {
);
};
const columns = [
const columns = useMemo(() => [
{
title: '患者姓名',
dataIndex: 'name',
@@ -191,7 +191,7 @@ export default function PatientTagManage() {
</AuthButton>
),
},
];
], [isDark, allTags, openTagModal]);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -112,7 +112,7 @@ export default function PointsOrderList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '订单号',
dataIndex: 'id',
@@ -198,7 +198,7 @@ export default function PointsOrderList() {
ellipsis: true,
render: (val: string | null) => val || '-',
},
];
], [getPatientName]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -180,7 +180,7 @@ export default function PointsProductList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '商品名称',
dataIndex: 'name',
@@ -270,7 +270,7 @@ export default function PointsProductList() {
</AuthButton>
),
},
];
], [openEdit, handleToggleActive, handleDelete]);
/** 抽屉表单分区 */
const formSections: FormSection[] = [

View File

@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useState, useCallback, useMemo } from 'react';
import {
Table,
Button,
@@ -184,7 +184,7 @@ export default function PointsRuleList() {
};
// ---- 列定义 ----
const columns = [
const columns = useMemo(() => [
{
title: '规则名称',
dataIndex: 'name',
@@ -286,7 +286,7 @@ export default function PointsRuleList() {
</AuthButton>
),
},
];
], [openEdit, handleToggleActive, handleDelete]);
return (
<PageContainer

View File

@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useState, useMemo } from 'react';
import { Table, Tag, Button, Modal, Form, Select, DatePicker, Input, message, Popconfirm, Space } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { dayjs } from '../../../utils/dayjs';
@@ -102,7 +102,7 @@ export function HealthRecordsTab({ patientId }: Props) {
}
};
const columns = [
const columns = useMemo(() => [
{ title: '记录类型', dataIndex: 'record_type', key: 'record_type', width: 120, render: (v: string) => <Tag>{RECORD_TYPE_MAP[v] || v}</Tag> },
{ title: '记录日期', dataIndex: 'record_date', key: 'record_date', width: 120 },
{ title: '内容', dataIndex: 'content', key: 'content', ellipsis: true },
@@ -139,7 +139,7 @@ export function HealthRecordsTab({ patientId }: Props) {
</Space>
),
},
];
], [openEditModal, handleDelete]);
return (
<div>

View File

@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useState, useMemo } from 'react';
import { Table, Tag, Button, Modal, Form, Input, DatePicker, message, Popconfirm, Space } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { dayjs } from '../../../utils/dayjs';
@@ -88,7 +88,7 @@ export function LabReportsTab({ patientId }: Props) {
}
};
const columns = [
const columns = useMemo(() => [
{ title: '报告日期', dataIndex: 'report_date', key: 'report_date', width: 120 },
{ title: '报告类型', dataIndex: 'report_type', key: 'report_type', width: 120, render: (v: string) => <Tag>{v}</Tag> },
{ title: '医生解读', dataIndex: 'doctor_interpretation', key: 'doctor_interpretation', ellipsis: true },
@@ -112,7 +112,7 @@ export function LabReportsTab({ patientId }: Props) {
</AuthButton>
),
},
];
], [openEditModal, handleDelete]);
return (
<div>