优化ProfileModules组件中的状态管理,使用选择器函数订阅匹配的客服对象,避免不必要的重新渲染。同时在DetailValue组件中引入useRef进行深度比较,确保只有在值真正变化时才更新编辑状态。
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState, useEffect } from "react";
|
||||
import React, { useCallback, useState, useEffect, useRef } from "react";
|
||||
import { Input, message } from "antd";
|
||||
import { Button } from "antd-mobile";
|
||||
import { EditOutlined } from "@ant-design/icons";
|
||||
@@ -56,8 +56,32 @@ const DetailValue: React.FC<DetailValueProps> = ({
|
||||
useState<Record<string, string>>(value);
|
||||
const [changedKeys, setChangedKeys] = useState<string[]>([]);
|
||||
|
||||
// 使用 useRef 存储上一次的 value,用于深度比较
|
||||
const prevValueRef = useRef<Record<string, string>>(value);
|
||||
|
||||
// 深度比较函数:比较两个对象的值是否真的变化了
|
||||
const isValueChanged = useCallback(
|
||||
(prev: Record<string, string>, next: Record<string, string>) => {
|
||||
const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);
|
||||
for (const key of allKeys) {
|
||||
if (prev[key] !== next[key]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
// 当外部value变化时,更新内部状态
|
||||
// 优化:只有当值真正变化时才重置编辑状态,避免因对象引用变化导致编辑状态丢失
|
||||
useEffect(() => {
|
||||
// 深度比较,只有当值真正变化时才更新
|
||||
if (!isValueChanged(prevValueRef.current, value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 只有在值真正变化时才更新状态
|
||||
setFieldValues(value);
|
||||
setOriginalValues(value);
|
||||
setChangedKeys([]);
|
||||
@@ -67,7 +91,10 @@ const DetailValue: React.FC<DetailValueProps> = ({
|
||||
newEditingFields[field.key] = false;
|
||||
});
|
||||
setEditingFields(newEditingFields);
|
||||
}, [value, fields]);
|
||||
|
||||
// 更新 ref
|
||||
prevValueRef.current = value;
|
||||
}, [value, fields, isValueChanged]);
|
||||
|
||||
const handleFieldChange = useCallback(
|
||||
(fieldKey: string, nextVal: string) => {
|
||||
|
||||
@@ -210,14 +210,34 @@ const Person: React.FC<PersonProps> = ({ contract }) => {
|
||||
|
||||
// 构建联系人或群聊详细信息
|
||||
|
||||
const customerList = useCustomerStore(state => state.customerList);
|
||||
const kfSelectedUser = useMemo(() => {
|
||||
if (!contract.wechatAccountId) return null;
|
||||
const matchedCustomer = customerList.find(
|
||||
customer => customer.id === contract.wechatAccountId,
|
||||
);
|
||||
return matchedCustomer || null;
|
||||
}, [customerList, contract.wechatAccountId]);
|
||||
// 优化:使用选择器函数直接订阅匹配的客服对象,避免订阅整个 customerList
|
||||
// 添加相等性比较,只有当匹配的客服对象或其 labels 真正变化时才触发重新渲染
|
||||
const kfSelectedUser = useCustomerStore(
|
||||
state => {
|
||||
if (!contract.wechatAccountId) return null;
|
||||
return (
|
||||
state.customerList.find(
|
||||
customer => customer.id === contract.wechatAccountId,
|
||||
) || null
|
||||
);
|
||||
},
|
||||
(prev, next) => {
|
||||
// 如果都是 null,认为相等
|
||||
if (!prev && !next) return true;
|
||||
// 如果一个是 null 另一个不是,认为不相等
|
||||
if (!prev || !next) return false;
|
||||
// 比较关键字段:id 和 labels(因为 useEffect 中使用了 labels)
|
||||
if (prev.id !== next.id) return false;
|
||||
// 比较 labels 数组是否真的变化了
|
||||
const prevLabels = prev.labels || [];
|
||||
const nextLabels = next.labels || [];
|
||||
if (prevLabels.length !== nextLabels.length) return false;
|
||||
// 深度比较 labels 数组内容(先复制再排序,避免修改原数组)
|
||||
const prevLabelsStr = JSON.stringify([...prevLabels].sort());
|
||||
const nextLabelsStr = JSON.stringify([...nextLabels].sort());
|
||||
return prevLabelsStr === nextLabelsStr;
|
||||
},
|
||||
);
|
||||
|
||||
// 不再需要从useContactStore获取getContactsByCustomer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user