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 { Table, Select, Tag, Space, message, Typography } from 'antd';
|
||||||
import { useThemeMode } from '../../hooks/useThemeMode';
|
import { useThemeMode } from '../../hooks/useThemeMode';
|
||||||
import { analysisApi, type AnalysisItem } from '../../api/ai/analysis';
|
import { analysisApi, type AnalysisItem } from '../../api/ai/analysis';
|
||||||
@@ -69,7 +69,7 @@ export default function AiAnalysisList() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '分析类型',
|
title: '分析类型',
|
||||||
dataIndex: 'analysis_type',
|
dataIndex: 'analysis_type',
|
||||||
@@ -112,7 +112,7 @@ export default function AiAnalysisList() {
|
|||||||
width: 170,
|
width: 170,
|
||||||
render: (v: string) => (v ? new Date(v).toLocaleString('zh-CN') : '-'),
|
render: (v: string) => (v ? new Date(v).toLocaleString('zh-CN') : '-'),
|
||||||
},
|
},
|
||||||
];
|
], []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -92,7 +92,7 @@ export default function AiPromptList() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -161,7 +161,7 @@ export default function AiPromptList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [handleActivate, handleRollback]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useEffect } from 'react';
|
import { useState, useCallback, useEffect, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -269,7 +269,7 @@ export default function AppointmentList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '患者',
|
title: '患者',
|
||||||
dataIndex: 'patient_name',
|
dataIndex: 'patient_name',
|
||||||
@@ -362,7 +362,7 @@ export default function AppointmentList() {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
], [handleStatusChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -128,7 +128,7 @@ export default function ArticleCategoryManage() {
|
|||||||
.filter((c) => !editingCategory || c.id !== editingCategory.id)
|
.filter((c) => !editingCategory || c.id !== editingCategory.id)
|
||||||
.map((c) => ({ label: c.name, value: c.id }));
|
.map((c) => ({ label: c.name, value: c.id }));
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '分类名称',
|
title: '分类名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -194,7 +194,7 @@ export default function ArticleCategoryManage() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [isDark, categories, openEditModal, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
@@ -242,7 +242,7 @@ export default function ArticleManageList() {
|
|||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
@@ -351,7 +351,7 @@ export default function ArticleManageList() {
|
|||||||
width: 200,
|
width: 200,
|
||||||
render: (_: unknown, record: ArticleListItem) => renderActions(record),
|
render: (_: unknown, record: ArticleListItem) => renderActions(record),
|
||||||
},
|
},
|
||||||
];
|
], [navigate, renderActions]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -94,7 +94,7 @@ export default function ArticleTagManage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '标签名称',
|
title: '标签名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -165,7 +165,7 @@ export default function ArticleTagManage() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [isDark, openEditModal, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useRef } from 'react';
|
import { useState, useCallback, useRef, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -199,7 +199,7 @@ export default function DoctorList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '姓名',
|
title: '姓名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -295,7 +295,7 @@ export default function DoctorList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEdit, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -202,7 +202,7 @@ export default function DoctorSchedule() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '日期',
|
title: '日期',
|
||||||
dataIndex: 'schedule_date',
|
dataIndex: 'schedule_date',
|
||||||
@@ -273,7 +273,7 @@ export default function DoctorSchedule() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEdit]);
|
||||||
|
|
||||||
// ---- 将日历数据转换为 CalendarView 所需格式 ----
|
// ---- 将日历数据转换为 CalendarView 所需格式 ----
|
||||||
const calendarScheduleMap: Record<string, ScheduleItem[]> = {};
|
const calendarScheduleMap: Record<string, ScheduleItem[]> = {};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -166,7 +166,7 @@ export default function OfflineEventList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '活动名称',
|
title: '活动名称',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
@@ -279,7 +279,7 @@ export default function OfflineEventList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEdit, handleCheckin, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<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 { useNavigate } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
@@ -184,7 +184,7 @@ export default function PatientList() {
|
|||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '姓名',
|
title: '姓名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -298,7 +298,7 @@ export default function PatientList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEditModal, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -86,7 +86,7 @@ export default function PatientTagManage() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '患者姓名',
|
title: '患者姓名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -191,7 +191,7 @@ export default function PatientTagManage() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [isDark, allTags, openTagModal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -112,7 +112,7 @@ export default function PointsOrderList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '订单号',
|
title: '订单号',
|
||||||
dataIndex: 'id',
|
dataIndex: 'id',
|
||||||
@@ -198,7 +198,7 @@ export default function PointsOrderList() {
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (val: string | null) => val || '-',
|
render: (val: string | null) => val || '-',
|
||||||
},
|
},
|
||||||
];
|
], [getPatientName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -180,7 +180,7 @@ export default function PointsProductList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '商品名称',
|
title: '商品名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -270,7 +270,7 @@ export default function PointsProductList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEdit, handleToggleActive, handleDelete]);
|
||||||
|
|
||||||
/** 抽屉表单分区 */
|
/** 抽屉表单分区 */
|
||||||
const formSections: FormSection[] = [
|
const formSections: FormSection[] = [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Button,
|
Button,
|
||||||
@@ -184,7 +184,7 @@ export default function PointsRuleList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ---- 列定义 ----
|
// ---- 列定义 ----
|
||||||
const columns = [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
title: '规则名称',
|
title: '规则名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -286,7 +286,7 @@ export default function PointsRuleList() {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEdit, handleToggleActive, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<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 { Table, Tag, Button, Modal, Form, Select, DatePicker, Input, message, Popconfirm, Space } from 'antd';
|
||||||
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||||
import { dayjs } from '../../../utils/dayjs';
|
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_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: 'record_date', key: 'record_date', width: 120 },
|
||||||
{ title: '内容', dataIndex: 'content', key: 'content', ellipsis: true },
|
{ title: '内容', dataIndex: 'content', key: 'content', ellipsis: true },
|
||||||
@@ -139,7 +139,7 @@ export function HealthRecordsTab({ patientId }: Props) {
|
|||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEditModal, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<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 { Table, Tag, Button, Modal, Form, Input, DatePicker, message, Popconfirm, Space } from 'antd';
|
||||||
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||||
import { dayjs } from '../../../utils/dayjs';
|
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_date', key: 'report_date', width: 120 },
|
||||||
{ title: '报告类型', dataIndex: 'report_type', key: 'report_type', width: 120, render: (v: string) => <Tag>{v}</Tag> },
|
{ title: '报告类型', dataIndex: 'report_type', key: 'report_type', width: 120, render: (v: string) => <Tag>{v}</Tag> },
|
||||||
{ title: '医生解读', dataIndex: 'doctor_interpretation', key: 'doctor_interpretation', ellipsis: true },
|
{ title: '医生解读', dataIndex: 'doctor_interpretation', key: 'doctor_interpretation', ellipsis: true },
|
||||||
@@ -112,7 +112,7 @@ export function LabReportsTab({ patientId }: Props) {
|
|||||||
</AuthButton>
|
</AuthButton>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
], [openEditModal, handleDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user