You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React DatePicker多月份显示时如何为所有月份添加年月下拉框

解决react-datepicker双月份视图下右侧月份显示年月下拉框的问题

默认情况下,react-datepicker的monthsShown={2}模式仅会在左侧月份显示年月选择下拉框,右侧月份没有。要实现两个月份都带可交互的下拉框,最可靠的方式是通过renderCustomHeader自定义头部组件,为每个月份单独渲染年月选择器。

修改后的完整代码

import React, { useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';

const DoubleMonthDatePicker = () => {
  const [startDate, setStartDate] = useState(new Date());
  const [endDate, setEndDate] = useState(null);
  const [displayedMonth, setDisplayedMonth] = useState(new Date());

  const onChange = (dates) => {
    const [start, end] = dates;
    setStartDate(start);
    setEndDate(end);
  };

  // 处理左侧月份的月份切换
  const handleLeftMonthChange = (month) => {
    const newDate = new Date(displayedMonth);
    newDate.setMonth(month);
    setDisplayedMonth(newDate);
  };

  // 处理左侧月份的年份切换
  const handleLeftYearChange = (year) => {
    const newDate = new Date(displayedMonth);
    newDate.setFullYear(year);
    setDisplayedMonth(newDate);
  };

  // 处理右侧月份的月份切换
  const handleRightMonthChange = (month) => {
    const newDate = new Date(displayedMonth);
    // 右侧月份是左侧+1,修改后同步左侧月份
    const rightMonthDate = new Date(newDate.setMonth(month - 1));
    setDisplayedMonth(rightMonthDate);
  };

  // 处理右侧月份的年份切换
  const handleRightYearChange = (year) => {
    const rightMonthDate = new Date(displayedMonth);
    rightMonthDate.setMonth(rightMonthDate.getMonth() + 1);
    rightMonthDate.setFullYear(year);
    // 同步左侧月份为右侧月份-1
    setDisplayedMonth(new Date(rightMonthDate.setMonth(rightMonthDate.getMonth() - 1)));
  };

  const renderCustomHeader = ({ decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled }) => {
    const leftMonth = new Date(displayedMonth);
    const rightMonth = new Date(displayedMonth);
    rightMonth.setMonth(rightMonth.getMonth() + 1);

    // 生成月份选项
    const monthOptions = Array.from({ length: 12 }, (_, i) => (
      <option key={i} value={i}>
        {new Date(0, i).toLocaleString('zh-CN', { month: 'long' })}
      </option>
    ));

    // 生成年份选项(近10年到未来10年)
    const yearOptions = Array.from({ length: 20 }, (_, i) => {
      const year = new Date().getFullYear() - 10 + i;
      return <option key={year} value={year}>{year}</option>;
    });

    return (
      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 10px' }}>
        {/* 左侧月份头部 */}
        <div className="react-datepicker__header">
          <div className="react-datepicker__current-month" style={{ display: 'flex', gap: '8px', justifyContent: 'center' }}>
            <select
              value={leftMonth.getMonth()}
              onChange={(e) => handleLeftMonthChange(Number(e.target.value))}
            >
              {monthOptions}
            </select>
            <select
              value={leftMonth.getFullYear()}
              onChange={(e) => handleLeftYearChange(Number(e.target.value))}
            >
              {yearOptions}
            </select>
          </div>
          <div className="react-datepicker__navigation-container">
            <button
              className="react-datepicker__navigation react-datepicker__navigation--previous"
              onClick={decreaseMonth}
              disabled={prevMonthButtonDisabled}
            >
              ❮
            </button>
            <button
              className="react-datepicker__navigation react-datepicker__navigation--next"
              onClick={increaseMonth}
              disabled={nextMonthButtonDisabled}
            >
              ❯
            </button>
          </div>
        </div>

        {/* 右侧月份头部 */}
        <div className="react-datepicker__header">
          <div className="react-datepicker__current-month" style={{ display: 'flex', gap: '8px', justifyContent: 'center' }}>
            <select
              value={rightMonth.getMonth()}
              onChange={(e) => handleRightMonthChange(Number(e.target.value))}
            >
              {monthOptions}
            </select>
            <select
              value={rightMonth.getFullYear()}
              onChange={(e) => handleRightYearChange(Number(e.target.value))}
            >
              {yearOptions}
            </select>
          </div>
        </div>
      </div>
    );
  };

  return (
    <DatePicker
      selected={startDate}
      onChange={onChange}
      startDate={startDate}
      endDate={endDate}
      selectsRange
      monthsShown={2}
      renderCustomHeader={renderCustomHeader}
      date={displayedMonth}
      onChangeMonth={(month) => setDisplayedMonth(month)}
    />
  );
};

export default DoubleMonthDatePicker;

关键说明

  1. 自定义头部渲染:通过renderCustomHeader属性完全控制两个月份的头部布局,分别为左侧和右侧月份添加年月选择下拉框。
  2. 同步月份状态:维护displayedMonth状态控制日历显示的起始月份,修改右侧月份时自动同步左侧月份,确保两个月份始终连续。
  3. 样式适配:通过内联样式调整头部元素布局,避免重叠,保证UI美观。

如果仅需要临时显示右侧月份的年月文本(无交互),可尝试CSS方案(依赖组件DOM结构,版本更新后可能失效):

.react-datepicker__month-container:nth-child(2) .react-datepicker__header {
  display: block !important;
}
.react-datepicker__month-container:nth-child(2) .react-datepicker__current-month {
  display: flex;
  gap: 8px;
  justify-content: center;
}

内容的提问来源于stack exchange,提问作者ashtash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:42:14