Material UI StaticDatePicker自定义日期样式后点击选日失效求助
解决StaticDatePicker自定义renderDay后无法点击选中日期的问题
问题根源
- 参数顺序错误:你对
renderDay的参数理解有误,MUI的renderDay并没有第四个dayComponent参数,第三个参数是包含isInCurrentMonth、disabled等属性的pickersDayProps对象。 - 丢失交互逻辑:你自定义的
<div>完全替换了MUI默认的日期单元格组件,原组件内置的点击选中、状态判断等交互逻辑被丢弃,导致点击日期无法触发选择。
解决方案
复用MUI默认的日期单元格组件,通过React.cloneElement扩展它的样式属性,同时保留原有的交互逻辑;同时修正renderDay的参数顺序,正确使用传入的属性。
修改后的代码
import React from 'react' import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' import { StaticDatePicker } from '@mui/x-date-pickers' import { LocalizationProvider } from '@mui/x-date-pickers' import { TextField } from '@mui/material' import { makeStyles } from '@mui/styles' import dayjs from 'dayjs' const styles = makeStyles(() => ({ pendingCloseDay: { backgroundColor: 'red', width: '35px', height: '35px', padding: '1px', }, closedDay: { backgroundColor: 'green', width: '35px', height: '35px', padding: '1px', }, noMovementsDay: { backgroundColor: 'white', width: '35px', height: '35px', padding: '1px' }, currentDay: { backgroundColor: 'blue', width: '35px', height: '35px', padding: '1px' }, futureDays: { backgroundColor: 'gray', width: '35px', height: '35px', padding: '1px' }, selectedDay: { backgroundColor: 'pink', width: '35px', height: '35px', padding: '1px' } })) const Calendar = ({date, setDate, setShow}) => { const classes = styles() const today = dayjs() const handleChange = (e) => { setDate(e) setShow(prev => !prev) } const mockDataForDays = (day, selectedDates, pickersDayProps) => { // 获取默认的日期单元格组件 const defaultDayComponent = pickersDayProps.children let randomValueForDay = Math.random() const isSelected = day.isSame(selectedDates[0], 'day') const isToday = day.isSame(today, 'day') let className = '' const { isInCurrentMonth, disabled } = pickersDayProps if (isInCurrentMonth) { if (disabled) { className = isSelected ? classes.selectedDay : isToday ? classes.currentDay : classes.futureDays } else if (randomValueForDay >= 0.66) { className = isSelected ? classes.selectedDay : isToday ? classes.currentDay : classes.noMovementsDay } else if (randomValueForDay >= 0.33) { className = isSelected ? classes.selectedDay : isToday ? classes.currentDay : classes.closedDay } else { className = isSelected ? classes.selectedDay : isToday ? classes.currentDay : classes.pendingCloseDay } // 克隆默认组件,添加自定义样式类,保留原组件的所有交互属性 return React.cloneElement(defaultDayComponent, { className: `${defaultDayComponent.props.className} ${className}` }) } // 非当前月份的日期返回默认组件 return defaultDayComponent } return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <StaticDatePicker sx={{'.MuiDayPicker-header': {gap: '0.5rem'}}} disableFuture={true} openTo='day' value={date} toolbarTitle='' onChange={handleChange} renderInput={params => <TextField {...params} />} componentsProps={{ actionBar: { actions: [] } }} renderDay={mockDataForDays} /> </LocalizationProvider> ) } export default Calendar
关键修改点
- 修正
renderDay参数:使用正确的参数顺序(day, selectedDates, pickersDayProps),从pickersDayProps中获取isInCurrentMonth、disabled等属性。 - 复用默认组件:通过
pickersDayProps.children获取MUI默认的日期单元格组件,用React.cloneElement为它添加自定义样式类,保留原有的点击选中逻辑。 - 优化日期判断:使用dayjs的
isSame方法更准确地判断日期是否选中或为当天,避免原代码中可能的数组访问错误。
这样修改后,既能保留自定义的日期样式,又能恢复点击日期选中的功能。
内容的提问来源于stack exchange,提问作者Roberto
相关产品推荐
相关产品推荐

