Redux 相关修改
This commit is contained in:
@@ -30,7 +30,13 @@ import { TimeIcon } from '@chakra-ui/icons';
|
||||
import EventScrollList from './DynamicNewsCard/EventScrollList';
|
||||
import DynamicNewsDetailPanel from './DynamicNewsDetail';
|
||||
import UnifiedSearchBox from './UnifiedSearchBox';
|
||||
import { fetchDynamicNews, toggleEventFollow, selectEventFollowStatus } from '../../../store/slices/communityDataSlice';
|
||||
import {
|
||||
fetchDynamicNews,
|
||||
toggleEventFollow,
|
||||
selectEventFollowStatus,
|
||||
selectVerticalEventsWithLoading,
|
||||
selectFourRowEventsWithLoading
|
||||
} from '../../../store/slices/communityDataSlice';
|
||||
import { usePagination } from './DynamicNewsCard/hooks/usePagination';
|
||||
import { PAGINATION_CONFIG } from './DynamicNewsCard/constants';
|
||||
|
||||
@@ -39,10 +45,6 @@ let dynamicNewsCardRenderCount = 0;
|
||||
|
||||
/**
|
||||
* 实时要闻·动态追踪 - 事件展示卡片组件
|
||||
* @param {Array} allCachedEvents - 完整缓存事件列表(从 Redux 传入)
|
||||
* @param {boolean} loading - 加载状态
|
||||
* @param {number} total - 服务端总数量
|
||||
* @param {number} cachedCount - 已缓存数量
|
||||
* @param {Object} filters - 筛选条件
|
||||
* @param {Array} popularKeywords - 热门关键词
|
||||
* @param {Date} lastUpdateTime - 最后更新时间
|
||||
@@ -53,11 +55,6 @@ let dynamicNewsCardRenderCount = 0;
|
||||
* @param {Object} ref - 用于滚动的ref
|
||||
*/
|
||||
const DynamicNewsCard = forwardRef(({
|
||||
allCachedEvents = [],
|
||||
loading,
|
||||
error,
|
||||
total = 0,
|
||||
cachedCount = 0,
|
||||
filters = {},
|
||||
popularKeywords = [],
|
||||
lastUpdateTime,
|
||||
@@ -67,9 +64,6 @@ const DynamicNewsCard = forwardRef(({
|
||||
onViewDetail,
|
||||
...rest
|
||||
}, ref) => {
|
||||
// 🔍 调试:记录每次渲染
|
||||
dynamicNewsCardRenderCount++;
|
||||
console.log(`%c🔍 [DynamicNewsCard] 渲染 #${dynamicNewsCardRenderCount} - allCachedEvents.length=${allCachedEvents.length}, total=${total}`, 'color: #FF9800; font-weight: bold; font-size: 14px;');
|
||||
const dispatch = useDispatch();
|
||||
const toast = useToast();
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
@@ -78,6 +72,47 @@ const DynamicNewsCard = forwardRef(({
|
||||
// 从 Redux 读取关注状态
|
||||
const eventFollowStatus = useSelector(selectEventFollowStatus);
|
||||
|
||||
// 本地状态:模式(先初始化,后面会被 usePagination 更新)
|
||||
const [currentMode, setCurrentMode] = useState('vertical');
|
||||
|
||||
// 根据当前模式从 Redux 读取对应的数据(添加默认值避免 undefined)
|
||||
const verticalData = useSelector(selectVerticalEventsWithLoading) || {};
|
||||
const fourRowData = useSelector(selectFourRowEventsWithLoading) || {};
|
||||
|
||||
// 🔍 调试:从 Redux 读取数据
|
||||
console.log('%c[DynamicNewsCard] 从 Redux 读取数据', 'color: #3B82F6; font-weight: bold;', {
|
||||
currentMode,
|
||||
'verticalData.data?.length': verticalData.data?.length || 0,
|
||||
'verticalData.total': verticalData.total,
|
||||
'verticalData.cachedCount': verticalData.cachedCount,
|
||||
'verticalData.loading': verticalData.loading,
|
||||
'fourRowData.data?.length': fourRowData.data?.length || 0,
|
||||
'fourRowData.total': fourRowData.total,
|
||||
});
|
||||
|
||||
// 根据模式选择数据源(添加默认值避免解构失败)
|
||||
const {
|
||||
data: allCachedEvents = [],
|
||||
loading = false,
|
||||
error = null,
|
||||
total = 0,
|
||||
cachedCount = 0
|
||||
} = currentMode === 'four-row' ? fourRowData : verticalData;
|
||||
|
||||
// 🔍 调试:选择的数据源
|
||||
console.log('%c[DynamicNewsCard] 选择的数据源', 'color: #3B82F6; font-weight: bold;', {
|
||||
mode: currentMode,
|
||||
'allCachedEvents.length': allCachedEvents.length,
|
||||
total,
|
||||
cachedCount,
|
||||
loading,
|
||||
error
|
||||
});
|
||||
|
||||
// 🔍 调试:记录每次渲染
|
||||
dynamicNewsCardRenderCount++;
|
||||
console.log(`%c🔍 [DynamicNewsCard] 渲染 #${dynamicNewsCardRenderCount} - mode=${currentMode}, allCachedEvents.length=${allCachedEvents.length}, total=${total}`, 'color: #FF9800; font-weight: bold; font-size: 14px;');
|
||||
|
||||
// 关注按钮点击处理
|
||||
const handleToggleFollow = useCallback((eventId) => {
|
||||
dispatch(toggleEventFollow(eventId));
|
||||
@@ -94,6 +129,8 @@ const DynamicNewsCard = forwardRef(({
|
||||
const hasInitialized = useRef(false);
|
||||
// 追踪是否已自动选中过首个事件
|
||||
const hasAutoSelectedFirstEvent = useRef(false);
|
||||
// 追踪筛选条件 useEffect 是否是第一次渲染(避免初始加载时重复请求)
|
||||
const isFirstRenderForFilters = useRef(true);
|
||||
|
||||
// 使用分页 Hook
|
||||
const {
|
||||
@@ -119,6 +156,24 @@ const DynamicNewsCard = forwardRef(({
|
||||
filters // 传递筛选条件
|
||||
});
|
||||
|
||||
// 同步 mode 到 currentMode
|
||||
useEffect(() => {
|
||||
setCurrentMode(mode);
|
||||
}, [mode]);
|
||||
|
||||
// 监听 error 状态,显示空数据提示
|
||||
useEffect(() => {
|
||||
if (error && error.includes('暂无更多数据')) {
|
||||
toast({
|
||||
title: '提示',
|
||||
description: error,
|
||||
status: 'info',
|
||||
duration: 2000,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
}, [error, toast]);
|
||||
|
||||
// 四排模式的事件点击处理(打开弹窗)
|
||||
const handleFourRowEventClick = useCallback((event) => {
|
||||
console.log('%c🔲 [四排模式] 点击事件,打开详情弹窗', 'color: #8B5CF6; font-weight: bold;', { eventId: event.id, title: event.title });
|
||||
@@ -126,34 +181,42 @@ const DynamicNewsCard = forwardRef(({
|
||||
onModalOpen();
|
||||
}, [onModalOpen]);
|
||||
|
||||
// 初始加载 - 只在组件首次挂载且未初始化时执行
|
||||
// 初始加载 - 只在组件首次挂载且对应模式数据为空时执行
|
||||
useEffect(() => {
|
||||
if (!hasInitialized.current && allCachedEvents.length === 0) {
|
||||
hasInitialized.current = true;
|
||||
dispatch(fetchDynamicNews({
|
||||
page: PAGINATION_CONFIG.INITIAL_PAGE,
|
||||
per_page: PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE,
|
||||
pageSize: PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE, // 传递 pageSize 确保索引计算一致
|
||||
mode: mode, // 传递当前模式
|
||||
per_page: pageSize,
|
||||
pageSize: pageSize, // 传递 pageSize 确保索引计算一致
|
||||
clearCache: true,
|
||||
...filters // 应用初始筛选条件
|
||||
...filters, // 先展开筛选条件
|
||||
page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数
|
||||
}));
|
||||
}
|
||||
}, [dispatch, allCachedEvents.length]);
|
||||
}, [dispatch, allCachedEvents.length, mode, pageSize]); // ✅ 移除 filters 依赖,避免重复触发
|
||||
|
||||
// 监听筛选条件变化 - 清空缓存并重新请求数据
|
||||
useEffect(() => {
|
||||
// 跳过初始加载(由上面的 useEffect 处理)
|
||||
if (!hasInitialized.current) return;
|
||||
|
||||
// 跳过第一次渲染(避免与初始加载 useEffect 重复)
|
||||
if (isFirstRenderForFilters.current) {
|
||||
isFirstRenderForFilters.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('%c🔍 [筛选] 筛选条件改变,重新请求数据', 'color: #8B5CF6; font-weight: bold;', filters);
|
||||
|
||||
// 筛选条件改变时,清空缓存并从第1页开始加载
|
||||
// 筛选条件改变时,清空对应模式的缓存并从第1页开始加载
|
||||
dispatch(fetchDynamicNews({
|
||||
page: PAGINATION_CONFIG.INITIAL_PAGE,
|
||||
mode: mode, // 传递当前模式
|
||||
per_page: pageSize,
|
||||
pageSize: pageSize,
|
||||
clearCache: true, // 清空缓存
|
||||
...filters // 应用新的筛选条件
|
||||
...filters, // 先展开筛选条件
|
||||
page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数
|
||||
}));
|
||||
}, [
|
||||
filters.sort,
|
||||
@@ -161,9 +224,26 @@ const DynamicNewsCard = forwardRef(({
|
||||
filters.q,
|
||||
filters.date_range,
|
||||
filters.industry_code,
|
||||
mode, // 添加 mode 到依赖
|
||||
pageSize, // 添加 pageSize 到依赖
|
||||
dispatch
|
||||
]); // 只监听筛选参数的变化,不监听 page
|
||||
|
||||
// 监听模式切换 - 如果新模式数据为空,请求数据
|
||||
useEffect(() => {
|
||||
if (hasInitialized.current && allCachedEvents.length === 0) {
|
||||
console.log(`%c🔄 [模式切换] ${mode} 模式数据为空,开始加载`, 'color: #8B5CF6; font-weight: bold;');
|
||||
dispatch(fetchDynamicNews({
|
||||
mode: mode,
|
||||
per_page: pageSize,
|
||||
pageSize: pageSize,
|
||||
clearCache: true,
|
||||
...filters, // 先展开筛选条件
|
||||
page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数
|
||||
}));
|
||||
}
|
||||
}, [mode]); // 只监听 mode 变化
|
||||
|
||||
// 自动选中逻辑 - 只在首次加载时自动选中第一个事件,翻页时不自动选中
|
||||
useEffect(() => {
|
||||
if (currentPageEvents.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user