react-datepicker 3.1.3:monthsShown>1时选中日期同步至上月问题咨询
monthsShown > 1 Hey there! Let's work through this frustrating bug you're hitting with react-datepicker 3.1.3. I've seen similar issues in older versions of the library, and here's what you can do to fix it:
Root Cause
This is a known bug in react-datepicker v3.1.3 specifically when using monthsShown={2}, showPreviousMonths={true}, and selectsRange together. The date selection sync logic gets confused across multiple displayed months, causing the selected date to incorrectly mirror in the previous month.
Solutions
1. Upgrade to a Newer Version (Recommended)
The simplest and most reliable fix is to upgrade react-datepicker to a newer stable release—this bug was addressed in later versions (starting around v4.x). To upgrade:
# Using npm npm install react-datepicker@latest # Using yarn yarn add react-datepicker@latest
Most core props like selectsRange, monthsShown, and showPreviousMonths are backward compatible, so you shouldn't need to rewrite much code. Just double-check the release notes for any minor API changes if you run into issues.
2. Manual Date Correction (If You Can't Upgrade)
If upgrading isn't an option right now, you can manually intercept the onChange event to fix the incorrectly synced dates. Here's a working example:
import { useState } from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; const RangeDatePicker = () => { const [selectedRange, setSelectedRange] = useState([null, null]); const handleRangeChange = (dates) => { let [startDate, endDate] = dates; // Fix: Ensure selected dates don't leak into the previous month const currentMonth = new Date().getMonth(); if (startDate && startDate.getMonth() !== currentMonth) { // Adjust start date to stay in the current month (tweak this to match your needs) startDate = new Date(startDate.getFullYear(), currentMonth, startDate.getDate()); } if (endDate && endDate.getMonth() !== currentMonth) { endDate = new Date(endDate.getFullYear(), currentMonth, endDate.getDate()); } setSelectedRange([startDate, endDate]); }; return ( <DatePicker shouldCloseOnSelect={false} selectsRange monthsShown={2} showPreviousMonths={true} selected={selectedRange[0]} startDate={selectedRange[0]} endDate={selectedRange[1]} onChange={handleRangeChange} /> ); }; export default RangeDatePicker;
This code checks if the selected date falls outside the current month and adjusts it to stay within the intended range. You can tweak the logic if you actually want to allow selecting dates from the previous month—just remove the month check and instead ensure the date selection doesn't duplicate across months.
3. Disable Selection in the Previous Month
If you only need to display the previous month's calendar (not allow selection), add enablePrevMonth={false} to make those dates unclickable. This prevents the sync bug entirely:
<DatePicker shouldCloseOnSelect={false} selectsRange monthsShown={2} showPreviousMonths={true} enablePrevMonth={false} />
内容的提问来源于stack exchange,提问作者Siva Kumar

