React中react-calendar向父组件传值失败问题求助
解决react-calendar月份传递异常与日历功能失效问题
看起来你踩了react-calendar的一个常见坑——value属性和月份切换逻辑的冲突,再加上Redux action触发时机的干扰,导致了现在的问题。我来帮你拆解一下原因,再给出具体的修复方案:
问题根源分析
value属性强制锁定月份:你给日历设置了value={this.state.date},这个属性会让日历始终显示state.date所在的月份。当你点击左右箭头切换月份时,虽然onActiveDateChange触发了,但日历会立刻跳回state.date对应的月份,看起来就像“停止工作”了。- Redux action触发时机不对:在
onActiveDateChange回调里直接触发Redux action会导致组件立即重渲染,此时日历的内部状态还没完全同步,传递的月份值自然会出现偏差,还会加重上述的月份跳转问题。
修复方案
1. 同步月份切换与组件state
当用户切换月份时,先更新state.date为当前显示月份的第一天(确保日历停留在新月份),再在setState的回调里触发Redux action——这样能保证状态更新完成后再传递值,避免偏差:
passActiveDate(activeStartDate) { const year = activeStartDate.getFullYear(); const month = activeStartDate.getMonth(); // 更新state.date为当前月份的第一天,让日历停留在新切换的月份 this.setState({ date: new Date(year, month, 1) }, () => { // 转为1-12的月份格式后传递给Redux const monthAfterPress = month + 1; this.props.activeMonthToPass(monthAfterPress); }); }
2. 检查Redux reducer逻辑
确认你的reducer在处理activeMonthToPass action时,没有对传入的月份值做错误修改(比如意外的加减操作),保证月份值能被正确保存到Redux状态中。
3. 可选:调整日历交互逻辑(按需选择)
如果你希望用户切换月份时,不改变当前选中的日期(仅查看其他月份),可以移除value={this.state.date}属性。这种情况下,日历可以自由切换月份,你需要通过tileClassName来自定义选中日期的样式,保持用户对选中日期的感知。
修复后的关键代码片段
class Calendario extends Component { state = { showHours: false, date: new Date() // 初始化当前日期 } onChange = date => this.setState({ date }, () => { const { chosenRoom } = this.props; const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const fullDate = `${year}/${month}/${day}`; const roomAndDayObj = {fullDate, chosenRoom}; this.props.sendRoomAndDay(roomAndDayObj); }) onClickDay(e) { this.setState({ showHours: true }); } passActiveDate(activeStartDate) { const year = activeStartDate.getFullYear(); const month = activeStartDate.getMonth(); this.setState({ date: new Date(year, month, 1) }, () => { const monthAfterPress = month + 1; this.props.activeMonthToPass(monthAfterPress); }); } render() { const { booked } = this.props; return ( <div> <div className="calendarsCont"> <Calendar onChange={this.onChange} onClickDay={(e) => this.onClickDay(e)} onActiveDateChange={({ activeStartDate }) => this.passActiveDate(activeStartDate)} value={this.state.date} locale="pl-PL" tileDisabled={({date, view }) => date.getDate()===15 && date.getMonth()===6 && date.getFullYear()===2018} /> </div> <div> {this.state.showHours ? <ChooseHour chosenDay={this.state.date} chosenRoom={this.props.chosenRoom}/> : null} </div> </div> ) } }
内容的提问来源于stack exchange,提问作者Murakami
相关产品推荐
相关产品推荐

