diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js index f893147a..9a6e1742 100644 --- a/src/views/Community/components/DynamicNewsCard.js +++ b/src/views/Community/components/DynamicNewsCard.js @@ -198,11 +198,14 @@ const DynamicNewsCard = forwardRef(({ // 初始加载 - 只在组件首次挂载且对应模式数据为空时执行 useEffect(() => { + // 添加防抖:如果已经初始化,不再执行 + if (hasInitialized.current) return; + const isDataEmpty = currentMode === 'vertical' ? Object.keys(allCachedEventsByPage || {}).length === 0 : (allCachedEvents?.length || 0) === 0; - if (!hasInitialized.current && isDataEmpty) { + if (isDataEmpty) { hasInitialized.current = true; dispatch(fetchDynamicNews({ mode: mode, // 传递当前模式 @@ -213,7 +216,7 @@ const DynamicNewsCard = forwardRef(({ page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数 })); } - }, [dispatch, allCachedEventsByPage, allCachedEvents, currentMode, mode, pageSize]); // ✅ 移除 filters 依赖,避免重复触发 + }, [dispatch, currentMode, mode, pageSize]); // 移除 allCachedEventsByPage, allCachedEvents 依赖,避免数据更新触发重复请求 // 监听筛选条件变化 - 清空缓存并重新请求数据 useEffect(() => { @@ -383,10 +386,8 @@ const DynamicNewsCard = forwardRef(({ totalPages={totalPages} onPageChange={handlePageChange} loading={loadingPage !== null} - loadingPage={loadingPage} error={error} mode={mode} - onModeChange={handleModeToggle} eventFollowStatus={eventFollowStatus} onToggleFollow={handleToggleFollow} hasMore={hasMore} diff --git a/src/views/Community/components/DynamicNewsCard/EventScrollList.js b/src/views/Community/components/DynamicNewsCard/EventScrollList.js index 715c43e9..a45ae759 100644 --- a/src/views/Community/components/DynamicNewsCard/EventScrollList.js +++ b/src/views/Community/components/DynamicNewsCard/EventScrollList.js @@ -12,6 +12,10 @@ import VerticalModeLayout from './VerticalModeLayout'; /** * 事件列表组件 - 支持纵向和平铺两种展示模式 * @param {Array} events - 当前页的事件列表(服务端已分页) + * @param {Array} displayEvents - 累积显示的事件列表(平铺模式用) + * @param {Function} loadNextPage - 加载下一页(无限滚动) + * @param {Function} loadPrevPage - 加载上一页(双向无限滚动) + * @param {Function} onFourRowEventClick - 平铺模式事件点击回调(打开弹窗) * @param {Object} selectedEvent - 当前选中的事件 * @param {Function} onEventSelect - 事件选择回调 * @param {string} borderColor - 边框颜色 @@ -19,19 +23,18 @@ import VerticalModeLayout from './VerticalModeLayout'; * @param {number} totalPages - 总页数(由服务端返回) * @param {Function} onPageChange - 页码改变回调 * @param {boolean} loading - 全局加载状态 - * @param {number|null} loadingPage - 正在加载的目标页码(用于显示"正在加载第X页...") + * @param {Object} error - 错误状态 * @param {string} mode - 展示模式:'vertical'(纵向分栏)| 'four-row'(平铺网格) - * @param {Function} onModeChange - 模式切换回调 * @param {boolean} hasMore - 是否还有更多数据 * @param {Object} eventFollowStatus - 事件关注状态 { [eventId]: { isFollowing, followerCount } } * @param {Function} onToggleFollow - 关注按钮回调 */ const EventScrollList = ({ events, - displayEvents, // 累积显示的事件列表(四排模式用) - loadNextPage, // 加载下一页(无限滚动) - loadPrevPage, // 加载上一页(双向无限滚动) - onFourRowEventClick, // 四排模式事件点击回调(打开弹窗) + displayEvents, + loadNextPage, + loadPrevPage, + onFourRowEventClick, selectedEvent, onEventSelect, borderColor, @@ -39,9 +42,8 @@ const EventScrollList = ({ totalPages, onPageChange, loading = false, - error, // 错误状态 + error, mode = 'vertical', - onModeChange, hasMore = true, eventFollowStatus = {}, onToggleFollow @@ -126,7 +128,7 @@ const EventScrollList = ({ {/* 纵向分栏模式 */} ); diff --git a/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js b/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js index aaaafc9d..e32d207a 100644 --- a/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js +++ b/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js @@ -6,7 +6,6 @@ import { Box, IconButton, Tooltip, VStack, Flex } from '@chakra-ui/react'; import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons'; import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard'; import EventDetailScrollPanel from './EventDetailScrollPanel'; -import PaginationControl from './PaginationControl'; /** * 纵向分栏模式布局 @@ -14,8 +13,7 @@ import PaginationControl from './PaginationControl'; * - detail(默认):左侧事件列表 1fr | 右侧详情 2fr * - list:左侧事件列表 7fr | 右侧详情 300px * - * 左侧使用分页模式,高度根据内容自适应,分页控制器在左侧列表底部 - * + * @param {string} display - CSS display 属性(用于显示/隐藏组件) * @param {Array} events - 当前页的事件列表(分页数据) * @param {Object} selectedEvent - 当前选中的事件 * @param {Function} onEventSelect - 事件选择回调 @@ -23,11 +21,9 @@ import PaginationControl from './PaginationControl'; * @param {Function} onToggleFollow - 关注按钮回调 * @param {Function} getTimelineBoxStyle - 时间线样式获取函数 * @param {string} borderColor - 边框颜色 - * @param {number} currentPage - 当前页码 - * @param {number} totalPages - 总页数 - * @param {Function} onPageChange - 页码改变回调 */ const VerticalModeLayout = ({ + display = 'flex', events, selectedEvent, onEventSelect, @@ -35,9 +31,6 @@ const VerticalModeLayout = ({ onToggleFollow, getTimelineBoxStyle, borderColor, - currentPage, - totalPages, - onPageChange, }) => { // 布局模式状态:'detail' = 聚焦详情(默认),'list' = 聚焦列表 const [layoutMode, setLayoutMode] = useState('list'); @@ -53,6 +46,7 @@ const VerticalModeLayout = ({ return ( ))} - - {/* 分页控制器 */} - {totalPages > 1 && ( - - - - )} {/* 右侧:事件详情 */} diff --git a/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js b/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js index 7fed9d90..d1304ccc 100644 --- a/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js +++ b/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js @@ -11,6 +11,7 @@ import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; /** * 虚拟化网格组件(支持多列布局 + 无限滚动) * @param {Object} props + * @param {string} props.display - CSS display 属性(用于显示/隐藏组件) * @param {Array} props.events - 事件列表(累积显示) * @param {number} props.columnsPerRow - 每行列数(默认 4,单列模式传 1) * @param {React.Component} props.CardComponent - 卡片组件(默认 DynamicNewsEventCard) @@ -25,6 +26,7 @@ import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; * @param {boolean} props.loading - 加载状态 */ const VirtualizedFourRowGrid = ({ + display = 'block', events, columnsPerRow = 4, CardComponent = DynamicNewsEventCard, @@ -92,6 +94,9 @@ const VirtualizedFourRowGrid = ({ * - 虚拟滚动缓存(渲染层):@tanstack/react-virtual 只渲染可见行,复用 DOM 节点 */ useEffect(() => { + // 如果组件被隐藏,不执行滚动监听 + if (display === 'none') return; + const scrollElement = parentRef.current; if (!scrollElement) return; @@ -136,7 +141,7 @@ const VirtualizedFourRowGrid = ({ scrollElement.addEventListener('scroll', handleScroll); return () => scrollElement.removeEventListener('scroll', handleScroll); - }, [loadNextPage, onRefreshFirstPage, hasMore, loading]); + }, [display, loadNextPage, onRefreshFirstPage, hasMore, loading]); /** * 【核心逻辑2】主动检测内容高度 - 确保内容始终填满容器 @@ -155,6 +160,9 @@ const VirtualizedFourRowGrid = ({ * - 监听 events.length 变化:新数据加载后重新检查 */ useEffect(() => { + // 如果组件被隐藏,不执行高度检测 + if (display === 'none') return; + const scrollElement = parentRef.current; if (!scrollElement || !loadNextPage) return; @@ -180,7 +188,7 @@ const VirtualizedFourRowGrid = ({ }, 500); return () => clearTimeout(timer); - }, [events.length, hasMore, loading, loadNextPage]); + }, [display, events.length, hasMore, loading, loadNextPage]); // 错误指示器(同行显示) const renderErrorIndicator = () => { @@ -244,8 +252,10 @@ const VirtualizedFourRowGrid = ({ return (