React中如何实现点击日历日期将值复制并存入数组(支持多选)
实现日历日期多选并存储到数组的方案
原代码存在的问题
- 变量名拼写错误:
selectedDya应为selectedDay - 更新状态时错误将数组转为对象:
setDates((prev) => ({...prev}, selectedDya))会把数组变成对象,正确操作应该针对数组进行 - 通过
e.target.textContent获取日期不可靠:若span内有其他嵌套元素,会导致获取内容错误,直接使用遍历的item更稳妥 - 未处理重复点击:重复点击同一日期会重复添加,应该支持点击切换选中状态(选中则取消,未选中则添加)
修正后的完整实现
import { useState } from 'react'; // 示例数据,可替换为你的实际数据结构 const data = [[['1', '2', '3', '4', '5', '6', '7']]]; const Calendar = () => { const [dates, setDates] = useState([]); const handleDateClick = (day) => { setDates(prevDates => { // 检查当前日期是否已在选中数组中 if (prevDates.includes(day)) { // 已选中则移除 return prevDates.filter(date => date !== day); } else { // 未选中则添加 return [...prevDates, day]; } }); }; return ( <section className='week'> {data[0][0].map((item, i) => ( <span key={i} onClick={() => handleDateClick(item)} // 可选:给选中的日期添加高亮样式 className={`cell ${dates.includes(item) ? 'selected' : ''}`} > {item} </span> ))} </section> ); }; export default Calendar;
关键逻辑说明
- 可靠获取日期:直接把遍历的
item传给点击事件,避免DOM文本内容的不确定性 - 切换选中状态:通过
includes判断日期是否已选中,已选中则用filter移除,未选中则用数组展开语法[...prevDates, day]添加 - 可选样式优化:给选中的日期添加
selected类名,方便做视觉区分(需自行编写对应CSS样式)
补充说明
如果你的日期是Date对象而非字符串,不能直接用includes判断,需要自定义比较逻辑,比如比较日期的时间戳:
// 假设day是Date对象 setDates(prevDates => { const isSelected = prevDates.some(date => date.getTime() === day.getTime()); if (isSelected) { return prevDates.filter(date => date.getTime() !== day.getTime()); } else { return [...prevDates, day]; } });
内容的提问来源于stack exchange,提问作者erza
相关产品推荐
相关产品推荐

