React Big Calendar自定义工具栏问题:周/日视图下上一页/下一页按钮无法按当前视图切换日期
解决React Big Calendar自定义工具栏的视图适配导航问题
我来帮你搞定这个问题!核心问题在于你的goToBack和goToNext方法没有根据当前视图来调整日期的增减逻辑,而是硬写了月份/天数的变更,导致不管在周/日视图下都会切换月份。我们可以利用React Big Calendar传给自定义工具栏的view属性,针对不同视图做对应的日期偏移处理。
修改后的完整代码
import { Stack, Box, IconButton, Typography } from '@mui/material'; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; // 假设你的SmallButton组件是自定义的,保持原引用即可 const CustomToolbar = ({ view, date, onNavigate, onView, open, setOpen }) => { // 回到今天的功能 const goToCurrent = () => { onNavigate(new Date()); }; // 上一页:根据当前视图调整日期偏移 const goToBack = () => { const newDate = new Date(date); switch(view) { case 'month': newDate.setMonth(newDate.getMonth() - 1); break; case 'week': newDate.setDate(newDate.getDate() - 7); break; case 'day': newDate.setDate(newDate.getDate() - 1); break; case 'agenda': // 议程视图按周偏移,可根据需求自定义 newDate.setDate(newDate.getDate() - 7); break; default: newDate.setMonth(newDate.getMonth() - 1); } onNavigate(newDate); }; // 下一页:根据当前视图调整日期偏移 const goToNext = () => { const newDate = new Date(date); switch(view) { case 'month': newDate.setMonth(newDate.getMonth() + 1); break; case 'week': newDate.setDate(newDate.getDate() + 7); break; case 'day': newDate.setDate(newDate.getDate() + 1); break; case 'agenda': newDate.setDate(newDate.getDate() + 7); break; default: newDate.setMonth(newDate.getMonth() + 1); } onNavigate(newDate); }; const goToWeekView = () => { onView("week"); }; const goToMonthView = () => { onView("month"); }; const goToDayView = () => { onView("day"); }; const goToAgendaView = () => { onView("agenda"); }; // 根据当前视图生成对应的日期标签 const getDateLabel = () => { if (view === 'month') { return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long' }).format(date); } else if (view === 'week') { const startOfWeek = new Date(date); startOfWeek.setDate(date.getDate() - date.getDay()); // 按周日为一周起始,可调整 const endOfWeek = new Date(startOfWeek); endOfWeek.setDate(startOfWeek.getDate() + 6); return `${new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' }).format(startOfWeek)} - ${new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(endOfWeek)}`; } else if (view === 'day') { return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }).format(date); } else if (view === 'agenda') { return 'All Events'; } return ''; }; return ( <Stack> <Box className="back-next-buttons"> <Stack direction="row" alignItems="center"> <IconButton onClick={goToBack} className="btn-back"> <ArrowBackIosIcon /> </IconButton> <Typography onClick={goToCurrent} style={{cursor: 'pointer'}}> Today </Typography> <IconButton onClick={goToNext} className="btn-back"> <ArrowForwardIosIcon/> </IconButton> </Stack> </Box> {/* 动态日期标签 */} <Typography> {getDateLabel()} </Typography> {/* 视图切换按钮 */} <Stack direction="row" flexWrap="wrap" alignItems="center"> <SmallButton onClick={goToWeekView} label="Week"/> <SmallButton onClick={goToMonthView} label="Month"/> <SmallButton onClick={goToDayView} label="Day"/> <SmallButton onClick={goToAgendaView} label="All Events"/> </Stack> </Stack> ); };
关键改动说明
- 解构核心Props:把自定义工具栏接收的
view、date、onNavigate等属性直接解构出来,避免原代码中直接操作toolbar对象的模糊性。 - 视图适配的日期偏移:通过
switch判断当前视图,给不同视图设置对应的日期增减逻辑:- 月视图:增减1个月
- 周视图:增减7天
- 日视图:增减1天
- 议程视图:默认按周偏移,可根据需求自定义
- 创建新Date对象:每次操作都用
new Date(date)创建新日期,避免直接修改原date引用导致的React状态更新问题。 - 完善辅助功能:补上了缺失的
goToCurrent(回到今天)函数,以及根据视图动态生成日期标签的getDateLabel函数,让工具栏显示更贴合当前视图。 - 修复原代码错误:原代码中的
toolbar.date.setDays是拼写错误,现在用新逻辑替换后无需再手动修改日期。
这样修改后,点击上一页/下一页按钮时,就会根据当前的视图(周/日/月)切换对应的日期区间了!
内容的提问来源于stack exchange,提问作者Bijay Poudel
相关产品推荐
相关产品推荐

