tech-book-labs
UI / インタラクション · 最終検証 2026-09-01 · @fullcalendar/react 7.0.2 · 初公開 2026-09-01

FullCalendar v7 を React で使う

FullCalendar v7 + React の最小構成。6 パッケージ→1 パッケージのサブパスに変わった v7 の構成(図解)、CSS 明示 import・temporal-polyfill という新しい前提、React state を正とするイベント管理(dateClick で追加 / ドラッグで移動 / クリックで削除)、日本語ロケールと 5 種の公式テーマまで。予定を追加・移動して試せる demo 付き。

fullcalendar calendar scheduler react ui

検証日: 2026-09-01

使用バージョン: @fullcalendar/react@7.0.2 + temporal-polyfill(React 19)

対象: 予定表 UI を React に組み込みたい / v6 の記事どおりに install したら v7 でパッケージが見つからない場面

業務アプリの定番カレンダー UI、FullCalendar の v7(2026 年の新メジャー)を React で動かす最小構成。v6 からパッケージ構成が根本的に変わったので、その変化を図解してから、予定の追加・移動・削除まで動く demo で確認します。

触って試す

日付をクリックすると入力欄の予定名で追加、予定をクリックで削除、ドラッグで別の日へ移動できる。右上のボタンで月 / 週 / リスト表示を切替。「日本語ロケール」のチェックを外すと、ボタン・曜日・「予定リスト」の文言が英語に切り替わる — ロケール 1 個で何が変わるかを目で確認できる。

v7 でパッケージ構成が変わった

v6 までの「本体 + プラグインを 1 個ずつ npm install」する構成は、v7 で @fullcalendar/react 1 パッケージのサブパスに統合された:

v6 まで: 6 パッケージを個別 install @fullcalendar/react @fullcalendar/core …/daygrid …/timegrid …/list …/interaction CSS は自動注入(import 不要) 日付処理は独自実装 v7 v7: 1 パッケージ + サブパス @fullcalendar/react …/react/daygrid …/react/timegrid …/react/list …/react/interaction …/themes/classic 等 5 種 …/locales/ja 等 CSS(skeleton + theme)は明示 import 必須 日付処理は Temporal(temporal-polyfill が peer) ※ 旧 @fullcalendar/daygrid 等の v7 は rc 止まり(2026-09-01 時点)。v7 は react パッケージのサブパスを使う
v6 → v7 のパッケージ構成。個別パッケージ 6 個が 1 パッケージのサブパスに統合され、テーマ・ロケールも同居する

npm view で確認すると、旧 @fullcalendar/daygrid 等の v7 は rc 版で止まっており(2026-09-01 時点)、v7 の view・interaction・テーマ・ロケールはすべて @fullcalendar/react/... のサブパスから import するのが正になっている。v6 の記事どおり @fullcalendar/daygrid@7 を入れようとすると見つからないのはこのため。

最小サンプル(install 2 つ + CSS の明示 import)

npm i @fullcalendar/react temporal-polyfill
項目
検証バージョン@fullcalendar/react@7.0.2
peer 要件React 17〜19 + temporal-polyfill(日付処理が Temporal ベースになったため必須)
TypeScript 型本体同梱(CalendarFunctionComponent<CalendarOptions>)
CSS自動注入されない — skeleton + テーマを明示 import
import Calendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/react/daygrid";
import classicTheme from "@fullcalendar/react/themes/classic";

import "@fullcalendar/react/skeleton.css";
import "@fullcalendar/react/themes/classic/theme.css";
import "@fullcalendar/react/themes/classic/palette.css";

function App() {
  return (
    <Calendar
      plugins={[dayGridPlugin, classicTheme]}
      initialView="dayGridMonth"
      events={[{ title: "リリース", start: "2026-09-10" }]}
    />
  );
}

React state を「正」にしてイベントを管理する

FullCalendar は内部にもイベントを保持できるが、React で使うなら events 配列の state を唯一の正にして、カレンダーは「描画とコールバック」に徹させると見通しがよい:

React state events: Ev[] データの正(source of truth) <Calendar> events を描画 ユーザー操作 日付クリック / ドラッグ / 予定クリック props 表示 dateClick / eventDrop / eventClick → setEvents(...) カレンダー内部にデータを持たせず、コールバックで state に反映 → 再描画で一巡
events 配列は React state に一本化し、FullCalendar は「描画とコールバック」に徹させる構成

demo の実装がそのままこの形。3 つのコールバックが state を更新し、更新された events が再描画される:

const [events, setEvents] = useState<Ev[]>([...]);

<Calendar
  plugins={[dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin, classicTheme]}
  events={events}
  editable                       // ドラッグ移動を有効化(interaction plugin が必要)
  dateClick={(info) =>           // 空き日付クリック → 追加
    setEvents((evs) => [...evs, { id: nextId(), title, start: info.dateStr }])}
  eventClick={(info) =>          // 予定クリック → 削除
    setEvents((evs) => evs.filter((e) => e.id !== info.event.id))}
  eventDrop={(info) =>           // ドラッグ完了 → 開始日を更新
    setEvents((evs) => evs.map((e) =>
      e.id === info.event.id ? { ...e, start: info.event.startStr } : e))}
/>

押さえどころ:

  • dateClick / editableinteractionPlugin が前提。plugins に入れ忘れるとクリックもドラッグも無反応(エラーは出ない)
  • イベントに id を必ず付ける。コールバックで受け取る info.event.id と state を突き合わせる鍵になる。無いと削除・移動の対象を特定できない
  • eventDropinfo.event.startStr はドラッグ後の新しい開始日。state に書き戻さないと、次の再描画で元の位置に戻る

日本語化はロケール 1 import

ボタン(今日 / 前 / 次)・曜日・リスト表示の文言は、サブパスのロケールを渡すだけで日本語になる:

import jaLocale from "@fullcalendar/react/locales/ja";

<Calendar locale={jaLocale} ... />

demo のチェックボックスはこの localejaLocale"en" で切り替えているだけ。祝日は入っていないので、祝日表示が要る場合は events として自分で流し込む。

テーマは 5 種類が同梱

v7 から公式テーマが 5 種(classic / monarch / breezy / forma / pulse)サブパスで同梱され、palette CSS の差し替えで配色だけ変えることもできる:

import monarchTheme from "@fullcalendar/react/themes/monarch";
import "@fullcalendar/react/themes/monarch/theme.css";
import "@fullcalendar/react/themes/monarch/palettes/blue.css";

demo は classic を使用。theme.css(構造)と palette.css(配色)が分かれているので、ダークテーマ対応は palette 側の CSS 変数を上書きする形で寄せられる。

つまずいたポイント

  • @fullcalendar/daygrid@7 が存在しない — v7 の view はサブパス(@fullcalendar/react/daygrid)。旧パッケージ名は rc で止まっている(本記事冒頭の図)
  • 画面が「文字の縦並び」になる — CSS の import 漏れ。skeleton.css + テーマの theme.css / palette.css の 3 つが必要
  • temporal-polyfill を入れ忘れると起動時に落ちる — v7 の peer dependency。エラーメッセージにパッケージ名が出るので指示どおり入れる
  • クリックもドラッグも反応しないinteractionPlugin の入れ忘れ。エラーにならず沈黙するので気づきにくい
  • ドラッグした予定が再描画で元に戻るeventDrop で state に書き戻していない。events を props で渡す構成では、カレンダー内部の変更は「提案」であって、確定は state 側の仕事
  • v6 流の CSS 上書きが効かない — v7 の class 名はビルド時ハッシュ付き(fc-classic-XpK のような形。DOM を実際に確認)。.fc-daygrid-day { ... } のようなクラス直指定のカスタム CSS は当たらない。見た目の調整は palette CSS の変数上書きか、data-date などの安定した属性・role 経由で行う
  • demo は client:only="react" で描画 — カレンダーは DOM 前提のため SSR では描画しない

関連書籍

tech-book.net /books/9784863543591

基礎から学ぶ React/React Hooks | tech-book.net

asakohattori · シーアンドアール研究所

本書では、 ・React/React Hooksの基本の習得 ・React/React Hooksを利用した簡単なアプリの作成ができる をゴールとし、つまずきやすいポ

この本が役立つ理由 — 本記事の state 管理(useState + コールバックで一巡させる形)は React Hooks の基本形そのもの。カレンダー以外にも通じる型をここで固められる
詳細を tech-book.net で見る
tech-book.net /books/9784297129163

TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発 | tech-book.net

手島 拓也/吉田 健人/高林 佳稀 · 技術評論社

新しいフロントエンドの入門書決定版! 本書はReact/Next.jsとTypeScriptを用いてWebアプリケーションを開発する入門書です

この本が役立つ理由 — 予定表のような業務 UI を TypeScript + React で作り切る実践書。イベントの型定義(本記事の Ev 型)を本格化する時の参照先に
詳細を tech-book.net で見る

関連記事 / 関連 Topic