Ver código fonte

refactor(products): 优化产品菜单客户端组件逻辑

- 使用 useMemo 计算初始选中的菜单项,提高性能
- 实现了默认展开父菜单的计算逻辑
- 添加了 URL 参数变化时的状态同步功能
- 简化了关键词参数处理逻辑
- 移除了冗余的异常捕获和日志输出
- 统一了菜单项选中和展开状态的管理方式
nahida 1 mês atrás
pai
commit
b63a186cb2
1 arquivos alterados com 45 adições e 41 exclusões
  1. 45 41
      src/components/products/ProductMenuClient.tsx

+ 45 - 41
src/components/products/ProductMenuClient.tsx

@@ -19,57 +19,61 @@ interface ProductMenuProps {
 export default function ProductMenu({menuItems, products}: ProductMenuProps) {
     const params = useSearchParams();
 
-    let baseSelect = '';
-    if (params.get('keyword')) {
-        baseSelect = params.get('keyword') || '';
-        try {
-            if (Object.is(params.get('keyword'), "软件产品")) {
-                if (menuItems.filter((item) => Object.is(item.key, "软件产品")).length > 0) {
-                    const list = menuItems.filter((item) => Object.is(item.key, "软件产品"));
-                    baseSelect = list[0].children?.[0].key || '';
-                }
-            } else if (Object.is(params.get('keyword'), "硬件产品")) {
-                if (menuItems.filter((item) => Object.is(item.key, "硬件产品")).length > 0) {
-                    const list = menuItems.filter((item) => Object.is(item.key, "硬件产品"));
-                    baseSelect = list[0].children?.[0].key || '';
-                }
+    const keywordParam = params.get('keyword');
+
+    // 1. 计算默认选中的 key
+    const initialSelectedKey = useMemo(() => {
+        let key = '';
+        if (keywordParam === '软件产品' || keywordParam === '硬件产品') {
+            const targetNode = menuItems.find((item) => item.key === keywordParam);
+            if (targetNode?.children?.length) {
+                key = targetNode.children[0].key;
+            } else if (targetNode) {
+                key = targetNode.key;
+            }
+        } else if (keywordParam) {
+            key = keywordParam; // 如果传了明确的子菜单key
+        }
+
+        // 如果没有带参数或者没匹配到,自动选择第一个菜单的第一个子项
+        if (!key && menuItems.length > 0) {
+            if (menuItems[0].children?.length) {
+                key = menuItems[0].children[0].key;
+            } else {
+                key = menuItems[0].key;
             }
-        } catch (e) {
-            console.log(e, "没有匹配到对应的菜单类型")
-            baseSelect = menuItems[0].children?.[0].key || '';
         }
-    } else if (menuItems[0]?.children) {
-        if (menuItems[0]?.children?.length > 0) {
-            baseSelect = menuItems[0].children?.[0].key || '';
+        return key;
+    }, [keywordParam, menuItems]);
+
+    // 2. 计算默认展开的父菜单
+    const initialExpandedKeys = useMemo(() => {
+        for (const item of menuItems) {
+            if (item.children?.some((child) => child.key === initialSelectedKey)) {
+                return [item.key];
+            }
         }
-    } else {
-        baseSelect = menuItems[0]?.key || '';
-    }
-    const [selectedKey, setSelectedKey] = useState(baseSelect)
-    const [expandedKeys, setExpandedKeys] = useState<string[]>([])
+        return [];
+    }, [initialSelectedKey, menuItems]);
+
+    const [selectedKey, setSelectedKey] = useState(initialSelectedKey);
+    const [expandedKeys, setExpandedKeys] = useState<string[]>(initialExpandedKeys);
+
+    // 监听 URL 变化,同步更新选中和展开状态
+    useEffect(() => {
+        setSelectedKey(initialSelectedKey);
+        setExpandedKeys(initialExpandedKeys);
+    }, [initialSelectedKey, initialExpandedKeys]);
+
     const showProductList = useMemo(
         () => products.filter((product) => product.productType === selectedKey),
         [products, selectedKey]
     );
-// 在 ProductMenuClient.tsx 中
+
     const normalizedProducts = showProductList.map(item => ({
         ...item,
         productUrl: item.productUrl ?? undefined // 把 null 转成 undefined
-    }))
-    useEffect(() => {
-        if (window.innerWidth > 640) {
-            for (const item of menuItems) {
-                if (item.children) {
-                    const child = item.children.find((child) => child.key === baseSelect)
-                    if (child) {
-                        // console.log(child)
-                        setExpandedKeys([item.key])
-                        break
-                    }
-                }
-            }
-        }
-    }, [menuItems, baseSelect])
+    }));
 
     const findLabelByKey = (key: string): string => {
         for (const item of menuItems) {