CodingMSTR LogoCodingMSTR
How to Build an Interactive Calendar in React with react-big-calendar

How to Build an Interactive Calendar in React with react-big-calendar

Free

Learn how to integrate react-big-calendar into your React app with event creation, editing, and popup modals.

Category: React
Added On: May 30, 2025
Developer: By Praveen
Youtube Video

For any customization or code setup, feel free to contact us. We also offer deployment on live servers.

For any issues related to downloading, email me at devpraveenkr@gmail.com

Need additional support or customization? Contact me!

Project Screenshots

Project Description

How to Build an Interactive Calendar in React with react-big-calendar

Create, Edit, and Manage Events in Style

Meta Description

Learn how to integrate `react-big-calendar` into your React app with event creation, editing, and popup modals. Step-by-step guide with code examples for building a full-featured calendar UI.

Overview

If you're building a React app and want to add a feature-rich calendar that allows users to view, create, and edit events, `react-big-calendar` is one of the best tools for the job.

In this tutorial, you’ll learn how to:

- Set up `react-big-calendar` in a React project

- Add 5 sample events

- Open a popup form when a date slot is clicked to add new events

- Edit events by clicking on them

- Maintain clean component structure with a dedicated popup component

Step 1: Install Dependencies

Install the required packages:

npm install react-big-calendar moment

Also install styles:

npm install react-big-calendar@latest moment@latest

Step 2: Set Up the Calendar Component

Create `CalendarComponent.jsx` and initialize `react-big-calendar` with moment localizer.

Code:

import { useState } from"react";
import {
    Calendar as BigCalendar,
    momentLocalizer,
    Views
} from"react-big-calendar";
import moment from"moment";
import"react-big-calendar/lib/css/react-big-calendar.css";
import EventPopup from"./EventPopup"; // <- Importing the popup component

const localizer = momentLocalizer(moment);

const initialEvents = [
    {
        id: 1,
        title: "Meeting with John",
        start: new Date(moment().add(1, 'days').set({ hour: 10, minute: 0 })),
        end: new Date(moment().add(1, 'days').set({ hour: 11, minute: 0 }))
    },
    {
        id: 2,
        title: "Lunch with Sarah",
        start: new Date(moment().subtract(20, 'days').set({ hour: 12, minute: 0 })),
        end: new Date(moment().subtract(20, 'days').set({ hour: 13, minute: 0 }))
    },
    {
        id: 3,
        title: "Project Deadline",
        start: new Date(moment().subtract(3, 'days').startOf("day")),
        end: new Date(moment().subtract(3, 'days').endOf("day"))
    },
    {
        id: 4,
        title: "Workshop",
        start: new Date(moment().subtract(10, 'days').set({ hour: 9, minute: 0 })),
        end: new Date(moment().subtract(10, 'days').set({ hour: 17, minute: 0 }))
    },
    {
        id: 5,
        title: "Team Standup",
        start: new Date(moment().subtract(15, 'days').set({ hour: 9, minute: 30 })),
        end: new Date(moment().subtract(15, 'days').set({ hour: 10, minute: 0 }))
    }
];

export default function CalendarComponent() {
    const [events, setEvents] = useState(initialEvents);
    const [selectedDate, setSelectedDate] = useState(null);
    const [isOpenEvent, setIsOpenEvent] = useState(false);
    const [selectedEvent, setSelectedEvent] = useState(null);

    const handleSelectEvent = (event) => {
        setSelectedEvent(event);
        setSelectedDate(null);
        setIsOpenEvent(true);
    };

    const handleSelectSlot = (slotInfo) => {
        setSelectedDate(slotInfo.start);
        setSelectedEvent(null);
        setIsOpenEvent(true);
    };

    const handleSaveEvent = (eventData) => {
        if (eventData.id) {
            // Editing existing
            setEvents((prev) =>
                prev.map((ev) => (ev.id === eventData.id ? eventData : ev))
            );
        } else {
            // Adding new
            const newEvent = {
                ...eventData,
                id: events.length + 1
            };
            setEvents((prev) => [...prev, newEvent]);
        }
        setIsOpenEvent(false);
        setSelectedDate(null);
        setSelectedEvent(null);
    };

    return (
        <>
            <div style={{ marginLeft: "100px", marginRight: "100px", marginTop: "100px" }}>
                <BigCalendar
                    selectable
                    localizer={localizer}
                    events={events}
                    startAccessor="start"
                    endAccessor="end"
                    onSelectSlot={handleSelectSlot}
                    onSelectEvent={handleSelectEvent}
                    style={{ height: '77vh' }}
                />
            </div>

            {isOpenEvent && (
                <EventPopup
                    isOpen={isOpenEvent}
                    onClose={() => setIsOpenEvent(false)}
                    onSave={handleSaveEvent}
                    date={selectedDate}
                    event={selectedEvent}
                />
            )}
        </>
    );
}



Step 3: Create the Event Popup Component

Now, let’s build the reusable `EventPopup` component to handle both adding and editing events.

Code:

import React, { useEffect, useState } from"react";

exportdefaultfunction EventPopup({ isOpen, onClose, onSave, date, event }) {
    const [title, setTitle] = useState("");
    const [start, setStart] = useState("");
    const [end, setEnd] = useState("");

    useEffect(() => {
        if (event) {
            setTitle(event.title || "");
            setStart(event.start.toISOString().slice(0, 16));
            setEnd(event.end.toISOString().slice(0, 16));
        } else if (date) {
            const defaultStart = new Date(date);
            const defaultEnd = new Date(defaultStart.getTime() + 60 * 60 * 1000); // 1 hour later
            setStart(defaultStart.toISOString().slice(0, 16));
            setEnd(defaultEnd.toISOString().slice(0, 16));
            setTitle("");
        }
    }, [date, event]);

    const handleSubmit = (e) => {
        e.preventDefault();
        onSave({
            id: event?.id,
            title,
            start: new Date(start),
            end: new Date(end),
        });
    };

    if (!isOpen) return null;

    return (
        <div style={{
            position: "fixed",
            top: 0, left: 0,
            width: "100vw", height: "100vh",
            backgroundColor: "rgba(0,0,0,0.4)",
            display: "flex", alignItems: "center", justifyContent: "center",
            zIndex: "10"
        }}>
            <div style={{ backgroundColor: "white", padding: "20px", borderRadius: "8px", width: "400px" }}>
                <h2>{event ? "Edit Event" : "Add Event"}</h2>
                <form onSubmit={handleSubmit}>
                    <div>
                        <label>Title:</label>
                        <input
                            type="text"
                            value={title}
                            onChange={(e) => setTitle(e.target.value)}
                            required
                            style={{ width: "90%", padding: "8px", marginBottom: "10px" }}
                        />
                    </div>
                    <div>
                        <label>Start:</label>
                        <input
                            type="datetime-local"
                            value={start}
                            onChange={(e) => setStart(e.target.value)}
                            required
                            style={{ width: "90%", padding: "8px", marginBottom: "10px" }}
                        />
                    </div>
                    <div>
                        <label>End:</label>
                        <input
                            type="datetime-local"
                            value={end}
                            onChange={(e) => setEnd(e.target.value)}
                            required
                            style={{ width: "90%", padding: "8px", marginBottom: "10px" }}
                        />
                    </div>
                    <button type="submit"style={{ marginRight: "10px", marginTop: "15px" }}>Save</button>
                    <button type="button"onClick={onClose}>Cancel</button>
                </form>
            </div>
        </div>
    );
}


Result

You now have a fully functional calendar in React with:

- 5 sample events

- Popup for adding new events by clicking a date

- Edit functionality by clicking existing events

- Clean component separation



Project Demo Video