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

React中FullCalendar无法显示Firebase来源事件的问题排查

问题:React中Firebase结合FullCalendar无法显示事件内容,仅显示日期标记
  • 在React项目中使用Firebase配合FullCalendar展示用户事件,控制台能打印出所有事件数据,但日历上仅显示存在事件的蓝色日期标记,无法看到具体事件内容。移除async/await语法后问题仍未解决。
  • 当前Firebase中的数据结构与之前正常运行的版本有差异,呈现嵌套状态。

当前代码(存在问题)

const DC = () => {
    const [events, setEvents] = useState([]);
    const [createEvent, setCreateEvent] = useState("")
    const [createDate, setCreateDate] = useState("")
    const [buttonDisabled, setButtonDisabled] = useState(false);
    console.log(events);

    const collectionRef = collection(db, 'calendar');

    const getEvents = () => {
        const q = query(collectionRef);
        getDocs(q).then((eventsD) => {
            let eventsData = eventsD.docs.map((doc) => ({
                ...doc.data(),
                id: doc.id
            }))
            setEvents(eventsData)
        }).catch((err) => {
            console.log(err)
        })
    }

    useEffect(() => {
        getEvents()
    }, [])


    //Add Task Handler
    const submitTask = async (e) => {
        e.preventDefault();
        try {
            await addDoc(collectionRef, {
                theEvent: createEvent,
                date: createDate,
                id: uuid(),
                timeStamp: serverTimestamp()
            })
            setButtonDisabled(true);
            window.location.reload();
        } catch (err) {
            console.log(err);
        }
    }

    return (
        <>
            {/* Modal Button */}
            <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#reminderModal">
                Add Reminder
            </button>


            <FullCalendar
                editable={true}
                selectable={true}
                events={events}
                headerToolbar={{
                    start: "today prev next",
                    end: "dayGridMonth dayGridWeek dayGridDay",
                }}
                plugins={[daygridPlugin, interactionPlugin]}
                views={["dayGridMonth", "dayGridWeek", "dayGridDay"]}
                handleWindowResize={true}
            />


            {/* Modal */}
            <div className="modal fade" id="reminderModal" tabindex="-1" aria-labelledby="reminderModalLabel" aria-hidden="true">
                <div className="modal-dialog">
                    <form className="d-flex" onSubmit={submitTask}>
                        <div className="modal-content">
                            <div className="modal-header">
                                <h1 className="modal-title fs-5" id="reminderModalLabel">Notify</h1>
                                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                            </div>
                            <div className="modal-body">
                                <form>
                                    <input
                                        type="date"
                                        className="form-control"
                                        onChange={(e) => setCreateDate(e.target.value)}
                                    />

                                    <input
                                        type="text"
                                        className="form-control"
                                        placeholder="State client's appointment details"
                                        onChange={(e) => setCreateEvent(e.target.value)}
                                    />
                                </form>
                            </div>
                            <div className="modal-footer">
                                <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                <button type="submit" className="btn btn-primary" disabled={buttonDisabled}>Add Notifier</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </>
    )
}

旧版正常代码

const DC = () => {
    const [events, setEvents] = useState({
        start: "",
        end: "",
        title: "",
        date: "",
        id: uuid(),
    });
    const [buttonDisabled, setButtonDisabled] = useState(false);
    console.log(events);

    const handleInput = (e) => {
        const { name, value } = e.target;
        setEvents({ ...events, [name]: value });
    }

    const collectionRef = collection(db, 'calendar');
    const getEvents = () => {
        const q = query(collectionRef);
        getDocs(q).then((eventsD) => {
            let eventsData = eventsD.docs.map((doc) => ({
                ...doc.data(),
                id: doc.id
            }))
            setEvents(eventsData)
        }).catch((err) => {
            console.log(err)
        })
    }

    useEffect(() => {
        getEvents()
    }, [])

    //Add Task Handler
    const submitTask = async (e) => {
        e.preventDefault();
        try {
            await addDoc(collectionRef, {
                ...events,
                timeStamp: serverTimestamp(),
            })
            setButtonDisabled(true);
            window.location.reload();
        } catch (err) {
            console.log(err);
        }
    }

    return (
        <>
            <div className='dc'>
                {/* Modal Button */}
                <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#reminderModal">
                    Add Reminder
                </button>

                <FullCalendar
                    editable={true}
                    selectable={true}
                    events={events}
                    headerToolbar={{
                        start: "today prev next",
                        end: "dayGridMonth dayGridWeek dayGridDay",
                    }}
                    plugins={[daygridPlugin, interactionPlugin]}
                    views={["dayGridMonth", "dayGridWeek", "dayGridDay"]}
                    handleWindowResize={true}
                />

            </div>

            {/* Modal */}
            <div className="modal fade" id="reminderModal" tabindex="-1" aria-labelledby="reminderModalLabel" aria-hidden="true">
                <div className="modal-dialog">
                    <form className="d-flex" onSubmit={submitTask}>
                        <div className="modal-content">
                            <div className="modal-header">
                                <h1 className="modal-title fs-5" id="reminderModalLabel">Notify</h1>
                                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                            </div>
                            <div className="modal-body">
                                <form>
                                    <input
                                        type="date"
                                        name="date"
                                        className="form-control"
                                        value={events.date}
                                        onChange={handleInput}
                                    />

                                    <input
                                        type="text"
                                        name="title"
                                        className="form-control"
                                        placeholder="State client's appointment details"
                                        value={events.title}
                                        onChange={handleInput}
                                    />
                                </form>
                            </div>
                            <div className="modal-footer">
                                <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                <button type="submit" className="btn btn-primary" disabled={buttonDisabled}>Add Notifier</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </>
    )
}

export default DC

问题分析

核心问题是事件字段与FullCalendar的要求不匹配:

  1. FullCalendar必须读取事件对象的title字段来显示事件内容,date/start字段来定位日期。
  2. 当前代码中,存入Firebase的事件内容字段是theEvent,而非FullCalendar识别的title;旧版代码使用title字段,因此能正常显示。
  3. 日历能显示蓝色标记,说明date字段被正确识别,但缺少title字段导致无法展示具体内容。

解决方案

两种修复方式任选其一即可:

方案1:修改数据映射,适配FullCalendar字段要求

在getEvents函数中,将Firebase返回的theEvent重命名为title:

const getEvents = () => {
    const q = query(collectionRef);
    getDocs(q).then((eventsD) => {
        let eventsData = eventsD.docs.map((doc) => ({
            ...doc.data(),
            title: doc.data().theEvent, // 映射字段名
            id: doc.id
        }))
        setEvents(eventsData)
    }).catch((err) => {
        console.log(err)
    })
}

方案2:修改添加事件的字段名,与旧版保持一致

在submitTask函数中,将theEvent改为title,直接存入符合要求的字段:

const submitTask = async (e) => {
    e.preventDefault();
    try {
        await addDoc(collectionRef, {
            title: createEvent, // 替换字段名
            date: createDate,
            id: uuid(),
            timeStamp: serverTimestamp()
        })
        setButtonDisabled(true);
        window.location.reload();
    } catch (err) {
        console.log(err);
    }
}

额外修复:移除无效嵌套表单

当前Modal中嵌套了两层<form>标签,属于无效HTML结构,会导致表单行为异常,建议移除内层<form>:

<div className="modal-body">
    {/* 移除内层<form>标签 */}
    <input
        type="date"
        className="form-control"
        onChange={(e) => setCreateDate(e.target.value)}
    />
    <input
        type="text"
        className="form-control"
        placeholder="State client's appointment details"
        onChange={(e) => setCreateEvent(e.target.value)}
    />
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:12:32