如何识别React-dates中用户选择日期的触发方式(回车/点击)
区分React-dates SingleDatePicker的日期选择触发方式(点击/回车)
我明白你不想额外添加addEventListener的诉求,其实可以利用React-dates组件本身暴露的回调来实现这个需求,不需要额外的监听器。下面是两种可行的方案:
方案1:利用组件内置的日期交互回调(推荐)
React-dates的SingleDatePicker支持传递底层DayPicker的props,其中包括onDayClick(鼠标点击日期时触发)和onDayKeyDown(日期单元格上触发键盘事件时调用)。我们可以通过这两个回调记录触发来源,再在onDateChange里判断:
class YourDatePickerComponent extends React.Component { state = { date: null, focused: false, triggerSource: null // 用来记录触发方式:'click' 或 'enter' }; handleDayClick = (day, e) => { // 鼠标点击日期单元格时,标记来源为click this.setState({ triggerSource: 'click' }); }; handleDayKeyDown = (day, e) => { // 当在日期单元格上按下回车键时,标记来源为enter if (e.key === 'Enter') { this.setState({ triggerSource: 'enter' }); } }; handleDateChange = (date) => { this.setState({ date }); if (date) { // 根据triggerSource判断触发方式 const source = this.state.triggerSource || 'unknown'; console.log(`日期通过${source === 'click' ? '鼠标点击' : '回车键'}选择`); this.props.onSaveValue(date.unix()); // 重置触发来源,避免影响下一次选择 this.setState({ triggerSource: null }); } }; render() { return ( <SingleDatePicker date={this.state.date} isOutsideRange={() => false} isDayHighlighted={day => isSameDay(moment(new Date()), moment(day))} daySize={30} verticalSpacing={2} onDateChange={this.handleDateChange} displayFormat={this.props.dateFormat} focused={this.state.focused} numberOfMonths={1} placeholder={this.props.dateFormat} onFocusChange={({ focused }) => { this.setState({ focused }); this.props.isCalendarOpen(focused); }} // 添加这两个回调来记录触发来源 onDayClick={this.handleDayClick} onDayKeyDown={this.handleDayKeyDown} /> ); } }
这个方案完全依赖组件本身的API,没有额外的事件监听器,非常符合你的需求。
方案2:通过父元素的React合成事件判断
如果出于某些原因无法使用onDayClick/onDayKeyDown,可以给SingleDatePicker包裹一个父元素,利用React的合成事件来判断触发方式:
class YourDatePickerComponent extends React.Component { state = { date: null, focused: false, triggerSource: null }; handleParentClick = (e) => { // 只在点击日期单元格时标记来源(通过类名判断,React-dates的日期单元格类名为CalendarDay) if (e.target.closest('.CalendarDay')) { this.setState({ triggerSource: 'click' }); } }; handleParentKeyDown = (e) => { // 只在日期单元格上按下回车时标记来源 if (e.key === 'Enter' && document.activeElement?.classList.contains('CalendarDay')) { this.setState({ triggerSource: 'enter' }); } }; handleDateChange = (date) => { this.setState({ date }); if (date) { const source = this.state.triggerSource || 'unknown'; console.log(`日期通过${source === 'click' ? '鼠标点击' : '回车键'}选择`); this.props.onSaveValue(date.unix()); this.setState({ triggerSource: null }); } }; render() { return ( <div onClick={this.handleParentClick} onKeyDown={this.handleParentKeyDown}> <SingleDatePicker // 你的原有props... date={this.state.date} isOutsideRange={() => false} isDayHighlighted={day => isSameDay(moment(new Date()), moment(day))} daySize={30} verticalSpacing={2} onDateChange={this.handleDateChange} displayFormat={this.props.dateFormat} focused={this.state.focused} numberOfMonths={1} placeholder={this.props.dateFormat} onFocusChange={({ focused }) => { this.setState({ focused }); this.props.isCalendarOpen(focused); }} /> </div> ); } }
这个方案需要注意类名的可靠性(React-dates的类名如果有变更可能需要调整),但同样不需要使用原生的addEventListener,而是用React的合成事件系统。
两种方案都能帮你区分用户是通过鼠标点击还是回车键选择日期,优先推荐方案1,因为它更贴合组件的设计,也更稳定。
内容的提问来源于stack exchange,提问作者Andre Voks
相关产品推荐
相关产品推荐

