Reactで開発しているアプリケーションに、カレンダー機能やスケジュール管理機能を加えたい、と考えたことがある人も多いはずです。
予約システム、タスク管理ツール、イベント告知サイトなど、カレンダーが活躍する場面は数多く存在します。
しかし、一言でカレンダーと言っても、
「デザインを完全に自由にしたいから、スクラッチで自作したい」
など、要件によって実装方法は大きく異なります。
この記事では、Reactでカレンダーを実装するための主要な2つのアプローチである、「ライブラリを利用する方法」と「スクラッチで自作する方法」について解説していきます。
【本記事の信頼性】
- 執筆者は元エンジニア
- 大手プログラミングスクールのWebディレクター兼ライターを経験
- 自らも地元密着型のプログラミングスクールを運営
受講生から評判の良いプログラミングスクール
スクール |
特徴 |
受講料金 |
大手比較サイトで4年連続人気NO.1!受講生からの評判も非常に高く、Web系のエンジニアを目指すならRUNTEQ一択。 | 657,000円 (最大約53万円の給付金が適用される) |
|
月単価80万円以上の現役エンジニア講師による指導!一度入会すればサポートは半永久的。 | 498,000円 |
|
格安で質の高いWeb制作スキルを習得したい人におすすめ!業界最安級の料金でありながら、コミュニティやサポートが充実。 | 129,800円~ |
|
完全無料でプログラミングが学べる貴重なスクール!最短1ヶ月で卒業可能。ゼロスク運営会社への就職もできる。 | 完全無料 |
|
長期間に渡って学習し、希少人材を目指す人に最適なスクール!受講料は高いものの、高収入を得られる人材を目指せる。 | 96~132万円 |
カレンダーライブラリを使って実装する方法
多くの場合、カレンダー機能は単に日付を表示するだけでなく、イベントの登録、表示、ドラッグ&ドロップでの変更など、複雑な機能が求められます。
これらの要求をゼロから作るのは非常に大変なため、まずは高機能なカレンダーライブラリの利用を検討するのが最も現実的で効率的な選択と言えるでしょう。
ここでは、数あるライブラリの中でも特に人気と実績のあるFullCalendar
を例に、導入から基本的な使い方までを解説していきます。
FullCalendarとは?
FullCalendar
は、多機能でカスタマイズ性が高く、商用利用も可能なオープンソースのJavaScriptカレンダーライブラリです。
React用の公式パッケージも提供されており、Reactプロジェクトに簡単に統合できます。
- 月・週・日表示の切り替え
- イベントのドラッグ&ドロップ、リサイズ
- 外部データソース(Google Calendarなど)との連携
- 豊富なUIカスタマイズオプション
など、本格的なスケジュールアプリケーションに必要な機能がほとんど揃っています。
FullCalendarの導入と基本的な使い方
それでは、実際にReactプロジェクトにFullCalendar
を導入してみましょう。
1. 必要なパッケージのインストール
まず、FullCalendar
本体とReact用アダプタ、そして基本的な月表示(daygrid)プラグインをインストールします。
npm install @fullcalendar/react @fullcalendar/daygrid
2. カレンダーコンポーネントの作成
次に、FullCalendar
を読み込んで表示するだけのシンプルなコンポーネントを作成します。
import React from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
const MyCalendar = () => {
return (
<div>
<FullCalendar
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
locale="ja" // 日本語化
headerToolbar={{ // ヘッダーのボタンやタイトル
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,dayGridWeek,dayGridDay'
}}
/>
</div>
);
};
export default MyCalendar;
3. イベント(予定)を表示する
カレンダーにイベントを表示するには、events
プロパティにイベント情報の配列を渡します。
import React from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
const MyCalendarWithEvents = () => {
const events = [
{ title: 'イベントA', start: '2025-10-20' },
{ title: 'イベントB', start: '2025-10-21', end: '2025-10-23' },
{ title: 'イベントC', start: '2025-10-25T10:30:00', allDay: false }
];
return (
<div>
<FullCalendar
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
locale="ja"
headerToolbar={{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,dayGridWeek,dayGridDay'
}}
events={events} // イベントデータを渡す
/>
</div>
);
};
export default MyCalendarWithEvents;
events
プロパティに、title
(イベント名)とstart
(開始日)を持つオブジェクトの配列を渡すだけで、カレンダー上に予定が表示されました。
終了日(end
)や終日設定(allDay
)も柔軟に指定できるのがわかりますね。
このように、FullCalendar
を使えば、驚くほど少ないコードで高機能なカレンダーを実装することが可能です。
スクラッチでカレンダーを自作する方法
「デザインをピクセル単位でこだわりたいから、UIは自分で組みたい」
そんな学習意欲の高い方や、デザインに強いこだわりを持つ方のために、ここからはReactでカレンダーをゼロから自作する方法を解説します。
日付の計算は非常に複雑で間違いやすいため、日付操作を簡単にするdate-fns
というライブラリの力を借りながら進めていきましょう。
1. 環境構築とdate-fnsのインストール
まず、Reactプロジェクトと、日付操作ライブラリdate-fns
をインストールします。
# Reactプロジェクトを作成
npx create-react-app my-calendar-app
cd my-calendar-app
# date-fnsをインストール
npm install date-fns
2. カレンダーコンポーネントの全体像
これから作成するカレンダーコンポーネントの骨格は以下のようになります。
年月をstate
で管理し、そのstate
を元にヘッダーと日付部分をレンダリングする構成です。
import React, { useState } from 'react';
import { format, addMonths, subMonths, startOfMonth, endOfMonth, startOfWeek, endOfWeek, isSameMonth, isSameDay, addDays } from 'date-fns';
import './Calendar.css'; // 簡単なスタイリング用
const Calendar = () => {
const [currentMonth, setCurrentMonth] = useState(new Date());
const renderHeader = () => {
// ... ヘッダー部分 (年月表示と月移動ボタン)
};
const renderDays = () => {
// ... 曜日部分 (日, 月, 火...)
};
const renderCells = () => {
// ... 日付セル部分 (1, 2, 3...)
};
return (
<div className="calendar">
{renderHeader()}
{renderDays()}
{renderCells()}
</div>
);
};
export default Calendar;
3. ヘッダー部分の実装
ヘッダーには、現在の年月を表示し、前月・翌月へ移動するためのボタンを配置します。
// Calendarコンポーネント内
const renderHeader = () => {
const dateFormat = "yyyy年 M月";
const prevMonth = () => {
setCurrentMonth(subMonths(currentMonth, 1));
};
const nextMonth = () => {
setCurrentMonth(addMonths(currentMonth, 1));
};
return (
<div className="header row">
<div className="col col-start" onClick={prevMonth}>
<span className="icon">chevron_left</span>
</div>
<div className="col col-center">
<span>{format(currentMonth, dateFormat)}</span>
</div>
<div className="col col-end" onClick={nextMonth}>
<span className="icon">chevron_right</span>
</div>
</div>
);
};
date-fns
のformat
で年月をフォーマットし、subMonths
とaddMonths
で月を移動させるstate
の更新関数を実装しています。
4. 曜日部分の実装
次に、日曜から土曜までの曜日を表示します。
// Calendarコンポーネント内
const renderDays = () => {
const days = [];
const date = ['日', '月', '火', '水', '木', '金', '土'];
for (let i = 0; i < 7; i++) {
days.push(
<div className="col col-center" key={i}>
{date[i]}
</div>
);
}
return <div className="days row">{days}</div>;
};
これは単純な配列のループで実現できますね。
5. 日付セル部分の実装(最重要)
ここがカレンダー実装の核となる部分です。
当月の日付だけでなく、カレンダーのマス目を埋める前月・翌月の日付も計算して表示する必要があります。
// Calendarコンポーネント内
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;
days.push(
<div
className={`col cell ${
!isSameMonth(day, monthStart)
? "disabled" // 当月でない日付はグレーアウト
: isSameDay(day, new Date()) ? "selected" : "" // 今日の日付をハイライト
}`}
key={day}
// onClick={() => onDateClick(cloneDay)} // 日付クリック時の処理はここで実装
>
<span className="number">{formattedDate}</span>
</div>
);
day = addDays(day, 1);
}
rows.push(
<div className="row" key={day}>
{days}
</div>
);
days = [];
}
return <div className="body">{rows}</div>;
};
処理の流れを分解すると、
startOfMonth
,endOfMonth
で当月の最初と最後の日付を取得。startOfWeek
,endOfWeek
で、その月が表示されるカレンダー領域の最初の日(日曜)と最後の日(土曜)を取得。while
ループで開始日から終了日まで1日ずつ増やしていく。- 7日ごとに
row
(週)を作成し、日付セルをdays
配列に追加していく。 isSameMonth
で当月以外の日付かを判定し、スタイルを切り替える。isSameDay
で今日の日付を判定し、スタイルを切り替える。
このロジックを実装することで、月を移動しても正しく日付が描画されるカレンダーが完成します。
まとめ
Reactでカレンダーを実装する2つの主要なアプローチを解説しました。
なお、Reactなどのライブラリや、その他のプログラミング言語を体系的に学び、効率よくスキルを高めるには、プログラミングスクールを利用するのも有効です。
細かな疑問がすぐに解決するだけでなく、現役エンジニアが「質の高いポートフォリオ」を作成するための手助けをしてくれたり、エンジニア就職・転職のコツを教えてくれたりするなど、様々なメリットがありますので、独学に疲れた方は検討してみてはいかがでしょうか。