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

在React中为Date-Picker添加日历图标并实现带弹窗日历的输入框

在React中实现带可点击日历图标的日期选择器

下面提供两种常见实现方案,分别基于第三方库和自定义开发,满足你的需求:

方案一:使用react-datepicker第三方库

这是最快捷的实现方式,react-datepicker是React生态中广泛使用的日期选择组件,支持自定义输入框样式。

1. 安装依赖

先安装必要的包:

npm install react-datepicker date-fns

2. 编写组件代码

我们通过customInput属性自定义带图标的输入框,点击图标或输入框都能弹出日历:

import React, { useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
// 这里用react-icons的日历图标,你也可以用其他图标库或本地图标
import { FaCalendar } from 'react-icons/fa';

// 自定义带图标的输入组件
const CustomDateInput = ({ value, onClick }) => (
  <div style={{ position: 'relative', width: '250px' }}>
    <input
      type="text"
      value={value}
      onClick={onClick}
      style={{
        width: '100%',
        padding: '8px 30px 8px 10px',
        boxSizing: 'border-box',
        border: '1px solid #ccc',
        borderRadius: '4px'
      }}
    />
    <FaCalendar
      onClick={onClick}
      style={{
        position: 'absolute',
        right: '8px',
        top: '50%',
        transform: 'translateY(-50%)',
        cursor: 'pointer',
        color: '#666'
      }}
    />
  </div>
);

const DatePickerWithIcon = () => {
  const [selectedDate, setSelectedDate] = useState(null);

  return (
    <DatePicker
      selected={selectedDate}
      onChange={(date) => setSelectedDate(date)}
      customInput={<CustomDateInput />}
      placeholderText="选择日期"
    />
  );
};

export default DatePickerWithIcon;

方案二:自定义实现(不依赖第三方库)

如果你需要完全自定义样式和逻辑,可以自己搭建输入框和日历组件:

1. 编写基础日历组件

先实现一个简化版的日历(用date-fns处理日期逻辑,也可以自己手动实现):

import { format, startOfMonth, endOfMonth, eachDayOfInterval } from 'date-fns';

const Calendar = ({ selectedDate, onDateSelect, onClose }) => {
  const currentMonth = selectedDate || new Date();
  const monthStart = startOfMonth(currentMonth);
  const monthEnd = endOfMonth(currentMonth);
  const days = eachDayOfInterval({ start: monthStart, end: monthEnd });

  return (
    <div style={{ border: '1px solid #ccc', padding: '8px', marginTop: '4px', position: 'absolute', background: 'white', zIndex: 100 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}>
        <button onClick={() => onDateSelect(new Date(currentMonth.setMonth(currentMonth.getMonth() - 1)))}>←</button>
        <h4>{format(currentMonth, 'yyyy-MM')}</h4>
        <button onClick={() => onDateSelect(new Date(currentMonth.setMonth(currentMonth.getMonth() + 1)))}>→</button>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '4px' }}>
        {['日', '一', '二', '三', '四', '五', '六'].map(day => (
          <div key={day} style={{ textAlign: 'center', fontWeight: 'bold' }}>{day}</div>
        ))}
        {days.map(day => (
          <div
            key={day.toString()}
            onClick={() => {
              onDateSelect(day);
              onClose();
            }}
            style={{
              textAlign: 'center',
              padding: '4px',
              cursor: 'pointer',
              backgroundColor: format(day, 'yyyy-MM-dd') === format(selectedDate || new Date(), 'yyyy-MM-dd') ? '#007bff' : 'transparent',
              color: format(day, 'yyyy-MM-dd') === format(selectedDate || new Date(), 'yyyy-MM-dd') ? 'white' : 'inherit'
            }}
          >
            {format(day, 'd')}
          </div>
        ))}
      </div>
    </div>
  );
};

export default Calendar;

2. 编写带图标的输入框组件

通过状态控制日历的显示/隐藏,点击图标触发切换:

import React, { useState } from 'react';
import { FaCalendar } from 'react-icons/fa';
import Calendar from './Calendar';
import { format } from 'date-fns';

const CustomDatePicker = () => {
  const [selectedDate, setSelectedDate] = useState(null);
  const [showCalendar, setShowCalendar] = useState(false);

  const toggleCalendar = () => {
    setShowCalendar(!showCalendar);
  };

  const handleDateSelect = (date) => {
    setSelectedDate(date);
  };

  return (
    <div style={{ position: 'relative', width: '250px' }}>
      <div onClick={toggleCalendar} style={{ position: 'relative' }}>
        <input
          type="text"
          value={selectedDate ? format(selectedDate, 'yyyy-MM-dd') : ''}
          placeholder="选择日期"
          style={{
            width: '100%',
            padding: '8px 30px 8px 10px',
            boxSizing: 'border-box',
            border: '1px solid #ccc',
            borderRadius: '4px'
          }}
          onClick={(e) => e.stopPropagation()} // 避免点击输入框时触发日历显示切换
        />
        <FaCalendar
          style={{
            position: 'absolute',
            right: '8px',
            top: '50%',
            transform: 'translateY(-50%)',
            cursor: 'pointer',
            color: '#666'
          }}
        />
      </div>
      {showCalendar && (
        <Calendar
          selectedDate={selectedDate}
          onDateSelect={handleDateSelect}
          onClose={() => setShowCalendar(false)}
        />
      )}
    </div>
  );
};

export default CustomDatePicker;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:54:20