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

React中如何通过onClick切换日历的事件创建表单与已存事件展示组件

实现日历点击切换事件表单/概览的解决方案

现有代码核心问题

  • 事件数据未关联对应日期,无法判断某一天是否存在已创建的事件
  • 缺少「当前选中日期」的状态记录,点击日期后不知道操作的是哪一天
  • setEventList 用法错误:原代码把数组类型的事件列表直接替换为单个事件对象,无法存储多组事件
  • Day 组件点击事件未传递当前日期参数,父组件拿不到点击的具体日期
  • Event 组件直接从数组类型的listEvent解构属性,会抛出运行时错误
  • HTML属性colspan在React中需写为驼峰格式colSpan,否则会触发语法警告

修改方案

状态设计调整

新增selectedDay状态记录当前点击的日期,所有的表单显示、事件判断逻辑都围绕该状态和事件列表的匹配结果实现。

逻辑调整

  1. 点击日期时,先记录当前选中的日期,再查询该日期是否有对应事件
  2. 提交事件时,给新事件绑定当前选中的日期后存入事件列表
  3. 根据选中日期的事件匹配结果,动态切换显示「创建表单」或「事件概览」

完整修改后代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 05:15:02