As a React developer, I’ve worked on a variety of projects that require calendar components, from booking systems to event schedulers. One thing I’ve learned is that building a calendar with event handling can be easy if you choose the right approach and tools.
In this article, I’ll walk you through creating a React calendar component that displays events, allows users to interact with dates, and is easy to customize for your needs. Whether you’re building an appointment scheduler for a US-based healthcare app or a local event planner, this tutorial will help you get started quickly.
Build a Custom React Calendar Component
Out of the box, React doesn’t provide a calendar component. While there are many third-party libraries like react-big-calendar or fullcalendar-react, sometimes you want a lightweight, customizable calendar tailored exactly to your use case.
From my experience, building a calendar from scratch or using minimal dependencies helps:
- Keep your bundle size small
- Control styling and UX
- Easily integrate with your backend or state management
Methods to Build a React Calendar with Events
There are two main approaches I recommend:
- Build a Calendar from Scratch Using Date Libraries
- Use a Lightweight Calendar Library and Extend It
I’ll explain both methods with code examples, so you can pick what suits your project best.
Method 1: Build a Calendar from Scratch Using date-fns
date-fns is a popular, lightweight date utility library. It simplifies date manipulation and formatting, which is crucial for building calendars.
Step 1: Set up React Project
If you don’t have a React app ready, create one using:
npx create-react-app react-calendar-events
cd react-calendar-events
npm install date-fnsStep 2: Create the Calendar Component
Here’s a full React component that renders a monthly calendar with clickable dates and displays events for selected dates.
import React, { useState } from 'react';
import { startOfMonth, endOfMonth, startOfWeek, endOfWeek, addDays, format, isSameMonth, isSameDay } from 'date-fns';
const events = {
'2025-11-28': [{ id: 1, title: 'Veterans Day Parade', time: '10:00 AM' }],
'2025-11-30': [{ id: 2, title: 'Thanksgiving Dinner', time: '6:00 PM' }],
'2025-12-05': [{ id: 3, title: 'Community Meeting', time: '4:00 PM' }],
};
function Calendar() {
const [currentMonth, setCurrentMonth] = useState(new Date());
const [selectedDate, setSelectedDate] = useState(new Date());
const renderHeader = () => {
const dateFormat = "MMMM yyyy";
return (
<div className="header row flex-middle">
<div className="col col-start">
<div className="icon" onClick={prevMonth}>‹</div>
</div>
<div className="col col-center">
<span>{format(currentMonth, dateFormat)}</span>
</div>
<div className="col col-end" onClick={nextMonth}>
<div className="icon">›</div>
</div>
</div>
);
};
const renderDays = () => {
const days = [];
const dateFormat = "EEEE";
const startDate = startOfWeek(currentMonth);
for (let i = 0; i < 7; i++) {
days.push(
<div className="col col-center" key={i}>
{format(addDays(startDate, i), dateFormat)}
</div>
);
}
return <div className="days row">{days}</div>;
};
const renderCells = () => {
const monthStart = startOfMonth(currentMonth);
const monthEnd = endOfMonth(monthStart);
const startDate = startOfWeek(monthStart);
const endDate = endOfWeek(monthEnd);
const rows = [];
let days = [];
let day = startDate;
let formattedDate = '';
while (day <= endDate) {
for (let i = 0; i < 7; i++) {
formattedDate = format(day, 'd');
const cloneDay = day;
const isoDate = format(day, 'yyyy-MM-dd');
const dayEvents = events[isoDate] || [];
days.push(
<div
className={`col cell ${!isSameMonth(day, monthStart)
? 'disabled'
: isSameDay(day, selectedDate) ? 'selected' : ''}`}
key={day}
onClick={() => onDateClick(cloneDay)}
>
<span className="number">{formattedDate}</span>
{dayEvents.length > 0 && <span className="event-indicator"></span>}
</div>
);
day = addDays(day, 1);
}
rows.push(
<div className="row" key={day}>
{days}
</div>
);
days = [];
}
return <div className="body">{rows}</div>;
};
const onDateClick = day => {
setSelectedDate(day);
};
const nextMonth = () => {
setCurrentMonth(addDays(currentMonth, 30));
};
const prevMonth = () => {
setCurrentMonth(addDays(currentMonth, -30));
};
const renderEvents = () => {
const isoDate = format(selectedDate, 'yyyy-MM-dd');
const dayEvents = events[isoDate] || [];
if (dayEvents.length === 0) {
return <div>No events for this day.</div>;
}
return (
<ul>
{dayEvents.map(event => (
<li key={event.id}>
<strong>{event.title}</strong> at {event.time}
</li>
))}
</ul>
);
};
return (
<div className="calendar">
{renderHeader()}
{renderDays()}
{renderCells()}
<div className="event-list">
<h3>Events on {format(selectedDate, 'MMMM d, yyyy')}</h3>
{renderEvents()}
</div>
</div>
);
}
export default Calendar;Step 3: Add Basic Styles
Add this CSS to App.css or your preferred stylesheet to make the calendar readable:
.calendar {
width: 350px;
margin: 20px auto;
font-family: Arial, sans-serif;
}
.header {
display: flex;
justify-content: space-between;
padding: 10px;
background: #0078d7;
color: white;
border-radius: 5px 5px 0 0;
}
.icon {
cursor: pointer;
user-select: none;
font-size: 20px;
}
.days {
display: flex;
background: #f0f0f0;
padding: 5px 0;
}
.col {
flex: 1;
text-align: center;
padding: 8px 0;
}
.body .row {
display: flex;
}
.cell {
flex: 1;
height: 60px;
border: 1px solid #ddd;
padding: 5px;
cursor: pointer;
position: relative;
}
.cell.disabled {
color: #ccc;
cursor: default;
}
.cell.selected {
background: #0078d7;
color: white;
}
.number {
display: block;
font-weight: bold;
}
.event-indicator {
width: 6px;
height: 6px;
background: red;
border-radius: 50%;
position: absolute;
bottom: 5px;
right: 5px;
}
.event-list {
margin-top: 20px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}Step 4: Use the Calendar Component
In your App.js, import and use the calendar:
import React from 'react';
import Calendar from './Calendar';
function App() {
return (
<div>
<h1>Community Events Calendar</h1>
<Calendar />
</div>
);
}
export default App;You can refer to the screenshot below to see the output.

Method 2: Use react-calendar Library with Custom Event Handling
If you want a quick solution, the react-calendar library is a great choice. It provides a calendar UI, and you can extend it to show events.
Step 1: Install react-calendar
npm install react-calendarStep 2: Create a Calendar with Events
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
const events = {
'2025-11-28': [{ id: 1, title: 'Veterans Day Parade', time: '10:00 AM' }],
'2025-11-30': [{ id: 2, title: 'Thanksgiving Dinner', time: '6:00 PM' }],
'2025-12-05': [{ id: 3, title: 'Community Meeting', time: '4:00 PM' }],
};
function EventCalendar() {
const [date, setDate] = useState(new Date());
const tileContent = ({ date, view }) => {
const isoDate = date.toISOString().split('T')[0];
if (view === 'month' && events[isoDate]) {
return <div className="event-dot"></div>;
}
return null;
};
const onChange = selectedDate => {
setDate(selectedDate);
};
const isoDate = date.toISOString().split('T')[0];
const dayEvents = events[isoDate] || [];
return (
<div>
<Calendar onChange={onChange} value={date} tileContent={tileContent} />
<h3>Events on {date.toDateString()}</h3>
{dayEvents.length === 0 ? (
<p>No events for this day.</p>
) : (
<ul>
{dayEvents.map(event => (
<li key={event.id}>
<strong>{event.title}</strong> at {event.time}
</li>
))}
</ul>
)}
<style>{`
.event-dot {
height: 6px;
width: 6px;
background: red;
border-radius: 50%;
margin-top: 2px;
margin-left: auto;
margin-right: auto;
}
`}</style>
</div>
);
}
export default EventCalendar;You can refer to the screenshot below to see the output.

This method is faster to implement and works well if you don’t want to build everything from scratch.
Building a React calendar component with event handling can be as simple or complex as your project requires. From my experience, the custom approach with date-fns offers full control and is perfect when you need a tailored UI. Meanwhile, libraries like react-calendar provide quick solutions with decent flexibility.
Choose the method that fits your timeline and project needs. Either way, you’ll have a functional calendar that can display and handle events for your US-based applications, like community events, holiday schedules, or appointment bookings.
You may also read:
- React Class Component Lifecycle Methods
- React Component Optimization Techniques
- React Class Components with Props
- Pass Props to Child Components in React

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.