Build a Calendar in React from Scratch
Creating a calendar application can be a rewarding project for both new and seasoned developers. In this guide, we’ll walk through the process of building a calendar using React, exploring key concepts along the way while ensuring our application is functionally robust and visually appealing.
Table of Contents
- Setting Up the Project
- Basic Structure of the Calendar
- Date Functions
- Creating the Calendar Component
- Event Handling
- Styling the Calendar
- Final Thoughts
Setting Up the Project
To get started, you’ll need to have Node.js and npm (Node Package Manager) installed. Once you’ve confirmed that you have those prerequisites, create a new React application using Create React App by running the following command in your terminal:
npx create-react-app react-calendar
Navigate into your project directory:
cd react-calendar
Now, open your project in your code editor of choice.
Basic Structure of the Calendar
The calendar will consist of the following components:
- Header: Displays the current month and year, along with navigation buttons to switch between months.
- Days: Represents the grid of days for the current month.
We’ll start by creating our main calendar component.
Creating the Calendar Component
Create a new file named Calendar.js in the src directory:
touch src/Calendar.js
Now, let’s define our Calendar component:
import React, { useState } from 'react';
const Calendar = () => {
const [currentDate, setCurrentDate] = useState(new Date());
return (
{currentDate.toLocaleString('default', { month: 'long' })} {currentDate.getFullYear()}
{/* Additional components will go here */}
);
};
export default Calendar;
In this initial setup, we have a simple Calendar component that utilizes React’s state to keep track of the current date.
Date Functions
To manage and display our calendar, we need utility functions to handle date calculations. Let’s create a new file named dateUtils.js in your src directory to house these utility functions:
export const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
export const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
export const addMonths = (date, months) => {
const dateCopy = new Date(date);
dateCopy.setMonth(date.getMonth() + months);
return dateCopy;
};
These functions will allow us to retrieve the number of days in a month, get the first day of the month (to adjust our calendar layout), and add or subtract months from our current date.
Creating the Calendar Grid
Next, we will populate our Calendar component with grid cells representing the days of the month. Inside the Calendar.js, we will build the grid structure:
import React, { useState } from 'react';
import { getDaysInMonth, getFirstDayOfMonth, addMonths } from './dateUtils';
const Calendar = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const daysInMonth = getDaysInMonth(currentDate.getFullYear(), currentDate.getMonth());
const firstDay = getFirstDayOfMonth(currentDate.getFullYear(), currentDate.getMonth());
const createCalendarGrid = () => {
const calendar = [];
for (let i = 0; i < firstDay; i++) calendar.push( ); // Pre-fill the empty days
for (let day = 1; day <= daysInMonth; day++) {
calendar.push({day} );
}
return Array.from({ length: 6 }, (_, i) => (
{calendar.slice(i * 7, i * 7 + 7)}
));
};
return (
{currentDate.toLocaleString('default', { month: 'long' })} {currentDate.getFullYear()}
Sun
Mon
Tue
Wed
Thu
Fri
Sat
{createCalendarGrid()}
);
};
export default Calendar;
This code generates a calendar grid for the current month. It creates the appropriate number of empty cells based on the first day of the month and fills in the days of the month.
Event Handling
Next, we need to implement the functionality that allows users to navigate between months. We’ll add buttons to go to the previous and next months. Update the Calendar.js component as shown below:
import React, { useState } from 'react';
import { getDaysInMonth, getFirstDayOfMonth, addMonths } from './dateUtils';
const Calendar = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const daysInMonth = getDaysInMonth(currentDate.getFullYear(), currentDate.getMonth());
const firstDay = getFirstDayOfMonth(currentDate.getFullYear(), currentDate.getMonth());
const createCalendarGrid = () => {
const calendar = [];
for (let i = 0; i < firstDay; i++) calendar.push( );
for (let day = 1; day <= daysInMonth; day++) {
calendar.push({day} );
}
return Array.from({ length: 6 }, (_, i) => (
{calendar.slice(i * 7, i * 7 + 7)}
));
};
const handlePrevMonth = () => setCurrentDate(addMonths(currentDate, -1));
const handleNextMonth = () => setCurrentDate(addMonths(currentDate, 1));
return (
{currentDate.toLocaleString('default', { month: 'long' })} {currentDate.getFullYear()}
Sun
Mon
Tue
Wed
Thu
Fri
Sat
{createCalendarGrid()}
);
};
export default Calendar;
This implementation incorporates two buttons that allow users to navigate between months, updating the current date accordingly.
Styling the Calendar
No calendar is complete without a bit of styling. You can add the following CSS to your App.css file to improve the visual aesthetics of your calendar:
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ccc;
height: 50px;
text-align: center;
}
th {
background-color: #f4f4f4;
}
button {
margin: 10px;
padding: 10px 15px;
font-size: 16px;
cursor: pointer;
}
This styling creates a clean and simple design for the calendar while ensuring that it remains user-friendly.
Final Thoughts
Congratulations! You have successfully built a calendar in React from scratch. This project allowed you to implement core React concepts such as state management, event handling, and functional programming. Feel free to expand upon this project by adding features like event creation, reminders, or even integrating it with a backend service for persistent event storage.
As you continue your journey in React development, remember that building small projects is an excellent way to sharpen your skills and reinforce what you’ve learned. Happy coding!
