refactor(web): 16 个列表页 columns 定义 useMemo 化 — 减少 Table 不必要 re-render
- AiPromptList/AiAnalysisList/AppointmentList 等 14 个主页面 - HealthRecordsTab/LabReportsTab 2 个 Tab 组件 - 每个 columns 依赖数组包含其引用的闭包变量(handleDelete/navigate 等)
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]> = {};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[] = [
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user