React中如何通过onClick切换日历的事件创建表单与已存事件展示组件
实现日历点击切换事件表单/概览的解决方案
现有代码核心问题
- 事件数据未关联对应日期,无法判断某一天是否存在已创建的事件
- 缺少「当前选中日期」的状态记录,点击日期后不知道操作的是哪一天
setEventList用法错误:原代码把数组类型的事件列表直接替换为单个事件对象,无法存储多组事件Day组件点击事件未传递当前日期参数,父组件拿不到点击的具体日期Event组件直接从数组类型的listEvent解构属性,会抛出运行时错误- HTML属性
colspan在React中需写为驼峰格式colSpan,否则会触发语法警告
修改方案
状态设计调整
新增selectedDay状态记录当前点击的日期,所有的表单显示、事件判断逻辑都围绕该状态和事件列表的匹配结果实现。
逻辑调整
- 点击日期时,先记录当前选中的日期,再查询该日期是否有对应事件
- 提交事件时,给新事件绑定当前选中的日期后存入事件列表
- 根据选中日期的事件匹配结果,动态切换显示「创建表单」或「事件概览」
完整修改后代码
Calendar 组件
import React, { useState } from 'react'; import Day from './Day'; import Event from './Event'; const Calendar = () => { // 存储所有事件,每个事件结构为 {id: string, title: string, day: string} const [eventList, setEventList] = useState([]); // 存储当前选中的日期 const [selectedDay, setSelectedDay] = useState(null); // 存储表单输入的事件名称 const [eventName, setEventName] = useState(""); // 日期点击处理 const handleDayClick = (day) => { setSelectedDay(day); setEventName(""); // 每次点击新日期清空表单输入 }; // 事件提交处理 const submitHandle = (e) => { e.preventDefault(); if (!eventName.trim()) { alert("请输入你的事件名称"); return; } const newEvent = { id: new Date().getTime().toString(), title: eventName.trim(), day: selectedDay // 绑定当前选中的日期 }; // 追加新事件到列表 setEventList([...eventList, newEvent]); setEventName(""); }; // 关闭弹窗/表单的方法,可按需绑定到取消/关闭按钮 const closeHandle = () => { setSelectedDay(null); }; // 查询当前选中日期的事件 const currentDayEvents = eventList.filter(item => item.day === selectedDay); return ( <> <table className="table-calendar"> <tr> <th colSpan="7">一月</th> </tr> <tr> <th>日</th> <th>一</th> <th>二</th> <th>三</th> <th>四</th> <th>五</th> <th>六</th> </tr> <tr> <Day day="1" onClick={handleDayClick}/> <Day day="2" onClick={handleDayClick}/> <Day day="3" onClick={handleDayClick}/> <Day day="4" onClick={handleDayClick}/> <Day day="5" onClick={handleDayClick}/> <Day day="6" onClick={handleDayClick}/> <Day day="7" onClick={handleDayClick}/> </tr> <tr> <Day day="8" onClick={handleDayClick}/> <Day day="9" onClick={handleDayClick}/> <Day day="10" onClick={handleDayClick}/> <Day day="11" onClick={handleDayClick}/> <Day day="12" onClick={handleDayClick}/> <Day day="13" onClick={handleDayClick}/> <Day day="14" onClick={handleDayClick}/> </tr> </table> {/* 选中日期后才渲染下方内容 */} {selectedDay && ( <div className="pop-container"> {/* 当天无事件时展示创建表单 */} {currentDayEvents.length === 0 ? ( <form className="event-form" onSubmit={submitHandle}> <h3>{selectedDay}日 - 创建事件</h3> <input type="text" placeholder="事件名称" className="event-name" value={eventName} onChange={(e) => setEventName(e.target.value)} /> <div className="btn-container"> <button type="submit" className="btn">提交</button> <button type="button" className="btn" onClick={closeHandle}>取消</button> </div> </form> ) : ( // 当天有事件时展示事件概览 <Event eventList={currentDayEvents} day={selectedDay} onClose={closeHandle}/> )} </div> )} </> ) } export default Calendar;
Day 组件示例(需补全传递点击参数)
import React from 'react'; const Day = ({ day, onClick }) => { return ( <td onClick={() => onClick(day)} className="day-cell"> {day} </td> ) } export default Day;
Event 组件调整
import React from 'react' const Event = ({ eventList, day, onClose }) => { return ( <div className="event-pop-up"> <h3>{day}日 - 事件概览</h3> {eventList.map(event => ( <div key={event.id} className="event-item"> <p>事件:{event.title}</p> </div> ))} <button type="button" className="btn" onClick={onClose}>关闭</button> </div> ) } export default Event
内容的提问来源于stack exchange,提问作者TheRealJohnDoe
相关产品推荐
相关产品推荐

