Redux 相关修改
This commit is contained in:
@@ -30,7 +30,13 @@ import { TimeIcon } from '@chakra-ui/icons';
|
|||||||
import EventScrollList from './DynamicNewsCard/EventScrollList';
|
import EventScrollList from './DynamicNewsCard/EventScrollList';
|
||||||
import DynamicNewsDetailPanel from './DynamicNewsDetail';
|
import DynamicNewsDetailPanel from './DynamicNewsDetail';
|
||||||
import UnifiedSearchBox from './UnifiedSearchBox';
|
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 { usePagination } from './DynamicNewsCard/hooks/usePagination';
|
||||||
import { PAGINATION_CONFIG } from './DynamicNewsCard/constants';
|
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 {Object} filters - 筛选条件
|
||||||
* @param {Array} popularKeywords - 热门关键词
|
* @param {Array} popularKeywords - 热门关键词
|
||||||
* @param {Date} lastUpdateTime - 最后更新时间
|
* @param {Date} lastUpdateTime - 最后更新时间
|
||||||
@@ -53,11 +55,6 @@ let dynamicNewsCardRenderCount = 0;
|
|||||||
* @param {Object} ref - 用于滚动的ref
|
* @param {Object} ref - 用于滚动的ref
|
||||||
*/
|
*/
|
||||||
const DynamicNewsCard = forwardRef(({
|
const DynamicNewsCard = forwardRef(({
|
||||||
allCachedEvents = [],
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
total = 0,
|
|
||||||
cachedCount = 0,
|
|
||||||
filters = {},
|
filters = {},
|
||||||
popularKeywords = [],
|
popularKeywords = [],
|
||||||
lastUpdateTime,
|
lastUpdateTime,
|
||||||
@@ -67,9 +64,6 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
onViewDetail,
|
onViewDetail,
|
||||||
...rest
|
...rest
|
||||||
}, ref) => {
|
}, 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 dispatch = useDispatch();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const cardBg = useColorModeValue('white', 'gray.800');
|
const cardBg = useColorModeValue('white', 'gray.800');
|
||||||
@@ -78,6 +72,47 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
// 从 Redux 读取关注状态
|
// 从 Redux 读取关注状态
|
||||||
const eventFollowStatus = useSelector(selectEventFollowStatus);
|
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) => {
|
const handleToggleFollow = useCallback((eventId) => {
|
||||||
dispatch(toggleEventFollow(eventId));
|
dispatch(toggleEventFollow(eventId));
|
||||||
@@ -94,6 +129,8 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
const hasInitialized = useRef(false);
|
const hasInitialized = useRef(false);
|
||||||
// 追踪是否已自动选中过首个事件
|
// 追踪是否已自动选中过首个事件
|
||||||
const hasAutoSelectedFirstEvent = useRef(false);
|
const hasAutoSelectedFirstEvent = useRef(false);
|
||||||
|
// 追踪筛选条件 useEffect 是否是第一次渲染(避免初始加载时重复请求)
|
||||||
|
const isFirstRenderForFilters = useRef(true);
|
||||||
|
|
||||||
// 使用分页 Hook
|
// 使用分页 Hook
|
||||||
const {
|
const {
|
||||||
@@ -119,6 +156,24 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
filters // 传递筛选条件
|
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) => {
|
const handleFourRowEventClick = useCallback((event) => {
|
||||||
console.log('%c🔲 [四排模式] 点击事件,打开详情弹窗', 'color: #8B5CF6; font-weight: bold;', { eventId: event.id, title: event.title });
|
console.log('%c🔲 [四排模式] 点击事件,打开详情弹窗', 'color: #8B5CF6; font-weight: bold;', { eventId: event.id, title: event.title });
|
||||||
@@ -126,34 +181,42 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
onModalOpen();
|
onModalOpen();
|
||||||
}, [onModalOpen]);
|
}, [onModalOpen]);
|
||||||
|
|
||||||
// 初始加载 - 只在组件首次挂载且未初始化时执行
|
// 初始加载 - 只在组件首次挂载且对应模式数据为空时执行
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasInitialized.current && allCachedEvents.length === 0) {
|
if (!hasInitialized.current && allCachedEvents.length === 0) {
|
||||||
hasInitialized.current = true;
|
hasInitialized.current = true;
|
||||||
dispatch(fetchDynamicNews({
|
dispatch(fetchDynamicNews({
|
||||||
page: PAGINATION_CONFIG.INITIAL_PAGE,
|
mode: mode, // 传递当前模式
|
||||||
per_page: PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE,
|
per_page: pageSize,
|
||||||
pageSize: PAGINATION_CONFIG.CAROUSEL_PAGE_SIZE, // 传递 pageSize 确保索引计算一致
|
pageSize: pageSize, // 传递 pageSize 确保索引计算一致
|
||||||
clearCache: true,
|
clearCache: true,
|
||||||
...filters // 应用初始筛选条件
|
...filters, // 先展开筛选条件
|
||||||
|
page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}, [dispatch, allCachedEvents.length]);
|
}, [dispatch, allCachedEvents.length, mode, pageSize]); // ✅ 移除 filters 依赖,避免重复触发
|
||||||
|
|
||||||
// 监听筛选条件变化 - 清空缓存并重新请求数据
|
// 监听筛选条件变化 - 清空缓存并重新请求数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 跳过初始加载(由上面的 useEffect 处理)
|
// 跳过初始加载(由上面的 useEffect 处理)
|
||||||
if (!hasInitialized.current) return;
|
if (!hasInitialized.current) return;
|
||||||
|
|
||||||
|
// 跳过第一次渲染(避免与初始加载 useEffect 重复)
|
||||||
|
if (isFirstRenderForFilters.current) {
|
||||||
|
isFirstRenderForFilters.current = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log('%c🔍 [筛选] 筛选条件改变,重新请求数据', 'color: #8B5CF6; font-weight: bold;', filters);
|
console.log('%c🔍 [筛选] 筛选条件改变,重新请求数据', 'color: #8B5CF6; font-weight: bold;', filters);
|
||||||
|
|
||||||
// 筛选条件改变时,清空缓存并从第1页开始加载
|
// 筛选条件改变时,清空对应模式的缓存并从第1页开始加载
|
||||||
dispatch(fetchDynamicNews({
|
dispatch(fetchDynamicNews({
|
||||||
page: PAGINATION_CONFIG.INITIAL_PAGE,
|
mode: mode, // 传递当前模式
|
||||||
per_page: pageSize,
|
per_page: pageSize,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
clearCache: true, // 清空缓存
|
clearCache: true, // 清空缓存
|
||||||
...filters // 应用新的筛选条件
|
...filters, // 先展开筛选条件
|
||||||
|
page: PAGINATION_CONFIG.INITIAL_PAGE, // 然后覆盖 page 参数
|
||||||
}));
|
}));
|
||||||
}, [
|
}, [
|
||||||
filters.sort,
|
filters.sort,
|
||||||
@@ -161,9 +224,26 @@ const DynamicNewsCard = forwardRef(({
|
|||||||
filters.q,
|
filters.q,
|
||||||
filters.date_range,
|
filters.date_range,
|
||||||
filters.industry_code,
|
filters.industry_code,
|
||||||
|
mode, // 添加 mode 到依赖
|
||||||
|
pageSize, // 添加 pageSize 到依赖
|
||||||
dispatch
|
dispatch
|
||||||
]); // 只监听筛选参数的变化,不监听 page
|
]); // 只监听筛选参数的变化,不监听 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(() => {
|
useEffect(() => {
|
||||||
if (currentPageEvents.length > 0) {
|
if (currentPageEvents.length > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user