perf: optimize reorder performance in BasicPanel

This commit is contained in:
JOYCEQL
2026-05-05 10:32:55 +08:00
parent 9ea60ac2f4
commit 0c00fb0a6b
+30 -9
View File
@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useCallback, useEffect, useRef, useState } from "react";
import { PlusCircle, GripVertical, Trash2, Eye, EyeOff } from "lucide-react"; import { PlusCircle, GripVertical, Trash2, Eye, EyeOff } from "lucide-react";
import { Reorder, AnimatePresence, motion } from "framer-motion"; import { Reorder, AnimatePresence, motion } from "framer-motion";
import { useTranslations } from "@/i18n/compat/client"; import { useTranslations } from "@/i18n/compat/client";
@@ -18,6 +18,7 @@ interface CustomFieldProps {
field: CustomFieldType; field: CustomFieldType;
onUpdate: (field: CustomFieldType) => void; onUpdate: (field: CustomFieldType) => void;
onDelete: (id: string) => void; onDelete: (id: string) => void;
onReorderEnd: () => void;
} }
const itemAnimations = { const itemAnimations = {
@@ -31,6 +32,7 @@ const CustomField: React.FC<CustomFieldProps> = ({
field, field,
onUpdate, onUpdate,
onDelete, onDelete,
onReorderEnd,
}) => { }) => {
const t = useTranslations("workbench.basicPanel"); const t = useTranslations("workbench.basicPanel");
@@ -39,6 +41,7 @@ const CustomField: React.FC<CustomFieldProps> = ({
value={field} value={field}
id={field.id} id={field.id}
className="group touch-none list-none" className="group touch-none list-none"
onDragEnd={onReorderEnd}
> >
<motion.div <motion.div
{...itemAnimations} {...itemAnimations}
@@ -169,16 +172,29 @@ const BasicPanel: React.FC = () => {
visible: field.visible ?? true, visible: field.visible ?? true,
})); }));
}); });
const basicFieldsRef = useRef(basicFields);
const customFieldsRef = useRef(customFields);
const t = useTranslations("workbench.basicPanel"); const t = useTranslations("workbench.basicPanel");
useEffect(() => {
basicFieldsRef.current = basicFields;
}, [basicFields]);
useEffect(() => {
customFieldsRef.current = customFields;
}, [customFields]);
const handleBasicReorder = (newOrder: BasicFieldType[]) => { const handleBasicReorder = (newOrder: BasicFieldType[]) => {
basicFieldsRef.current = newOrder;
setBasicFields(newOrder); setBasicFields(newOrder);
updateBasicInfo({
...basic,
fieldOrder: newOrder,
});
}; };
const commitBasicReorder = useCallback(() => {
updateBasicInfo({
fieldOrder: basicFieldsRef.current,
});
}, [updateBasicInfo]);
const toggleFieldVisibility = (fieldId: string, isVisible: boolean) => { const toggleFieldVisibility = (fieldId: string, isVisible: boolean) => {
const newFields = basicFields.map((field) => const newFields = basicFields.map((field) =>
field.id === fieldId ? { ...field, visible: isVisible } : field field.id === fieldId ? { ...field, visible: isVisible } : field
@@ -245,13 +261,16 @@ const BasicPanel: React.FC = () => {
}; };
const handleCustomFieldsReorder = (newOrder: CustomFieldType[]) => { const handleCustomFieldsReorder = (newOrder: CustomFieldType[]) => {
customFieldsRef.current = newOrder;
setCustomFields(newOrder); setCustomFields(newOrder);
updateBasicInfo({
...basic,
customFields: newOrder,
});
}; };
const commitCustomFieldsReorder = useCallback(() => {
updateBasicInfo({
customFields: customFieldsRef.current,
});
}, [updateBasicInfo]);
const renderBasicField = (field: BasicFieldType) => { const renderBasicField = (field: BasicFieldType) => {
const selectedIcon = basic?.icons?.[field.key] || "User"; const selectedIcon = basic?.icons?.[field.key] || "User";
@@ -262,6 +281,7 @@ const BasicPanel: React.FC = () => {
key={field.id} key={field.id}
className="group touch-none list-none" className="group touch-none list-none"
dragListener={field.key !== "name" && field.key !== "title"} dragListener={field.key !== "name" && field.key !== "title"}
onDragEnd={commitBasicReorder}
> >
<motion.div <motion.div
{...itemAnimations} {...itemAnimations}
@@ -428,6 +448,7 @@ const BasicPanel: React.FC = () => {
field={field} field={field}
onUpdate={updateCustomField} onUpdate={updateCustomField}
onDelete={deleteCustomField} onDelete={deleteCustomField}
onReorderEnd={commitCustomFieldsReorder}
/> />
))} ))}
</Reorder.Group> </Reorder.Group>