同一页面双connectHierarchicalMenu组件适配不同设备时的同名Facet报错问题
问题原因
你遇到的报错是因为:
- SSR与客户端hydrate不匹配:SSR阶段
window不存在,isDesktop为false,会渲染<SmallFilter />;客户端hydrate时如果当前是桌面尺寸,isDesktop变为true,此时<BigFilter />开始渲染,但<SmallFilter />还未完成卸载,导致两个基于connectHierarchicalMenu()的组件同时存在,重复注册了同名facet。 - 渲染阶段的组件初始化逻辑:直接用变量判断的方式,React渲染过程中可能会解析两个条件分支的组件(即使条件不满足),导致
connectHierarchicalMenu被调用两次。
解决方案
方案一:使用状态+useEffect控制组件渲染
通过状态管理当前显示的组件,配合窗口resize监听,确保同一时间只有一个组件被挂载:
import { useState, useEffect } from 'react'; const Example = () => { const THRESHOLD = 1000; const [isDesktop, setIsDesktop] = useState(false); useEffect(() => { // 检测屏幕尺寸并更新状态 const checkScreenSize = () => { setIsDesktop(window.innerWidth > THRESHOLD); }; // 初始执行一次 checkScreenSize(); // 监听窗口resize事件 window.addEventListener('resize', checkScreenSize); // 清理监听器 return () => window.removeEventListener('resize', checkScreenSize); }, []); // SSR阶段返回占位,避免hydrate不匹配 if (typeof window === 'undefined') { return <div></div>; } return ( <div> {isDesktop ? <BigFilter /> : <SmallFilter />} </div> ); };
方案二:动态导入组件(彻底避免重复初始化)
通过动态导入的方式,只有满足尺寸条件时才加载对应的组件,从根源上防止另一个组件被初始化:
import { useState, useEffect } from 'react'; const DynamicFilter = () => { const THRESHOLD = 1000; const [FilterComponent, setFilterComponent] = useState(null); useEffect(() => { const loadFilterComponent = () => { if (window.innerWidth > THRESHOLD) { import('./BigFilter').then(module => setFilterComponent(module.default)); } else { import('./SmallFilter').then(module => setFilterComponent(module.default)); } }; // 初始加载对应组件 loadFilterComponent(); // 监听resize切换组件 const handleResize = () => loadFilterComponent(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // 加载状态下返回占位 if (!FilterComponent) { return <div></div>; } return <FilterComponent />; }; const Example = () => { return ( <div> <DynamicFilter /> </div> ); };
关键注意点
- 不要在渲染阶段直接通过
window.innerWidth判断切换组件,React的渲染逻辑可能会解析两个分支的组件,导致重复注册。 - SSR阶段必须返回与客户端初始渲染一致的内容(如占位),避免hydrate不匹配的问题。
内容的提问来源于stack exchange,提问作者Siavash
相关产品推荐
相关产品推荐

