LoginSignup
53
33

More than 1 year has passed since last update.

React + TypeScript + FullCalendar: 簡単なカレンダーをつくる

Last updated at Posted at 2021-06-28

FullCalendarは、さまざまにカスタマイズしたカレンダーがつくれるオープンソース1のJavaScriptライブラリです。ReactやVueそしてAngularといったフレームワークにも対応しています。とくに、Reactについては、バーチャルDOMノードを生成するという踏み込んだつくり込みです。

とはいえ、まだReactを用いた情報があまりなく、TypeScriptまで含めると、調べるのに苦労するのが現状です。本稿では、ReactとTypeScriptを使って、FullCalendarによるごく簡単なカレンダーのサンプルをつくってみます(図001)。なお、公式サイトのコードサンプルは、多くがクラスを用いています。本稿では、今主流となりつつある関数コンポーネントでコードを書くことにしました。

サンプル001■React + TypeScript + FullCalendar: Basic calendar

2106002_003.png
>> CodeSandboxへ

React + TypeScriptのひな形作成とFullCalendarのインストール

Reactアプリケーションのひな型は、Create React Appを使うのが簡単です(「Create React App 入門 01: 3×3マスのゲーム盤をつくる」01「Reactアプリケーションのひな形をつくる」)。コマンドのオプションに--template typescriptを加えれば、プロジェクトにTypeScriptの設定が含まれます(プロジェクト名はreact-typescript-fullcalendarとしました)。

npx create-react-app react-typescript-fullcalendar --template typescript

つぎに、プロジェクトのディレクトリ(react-typescript-fullcalendar)に切り替えて、FullCalendarのインストールです。カレンダーのビューに使うプラグインのdaygridも加えてください。

npm install --save @fullcalendar/react @fullcalendar/daygrid

カレンダーを表示する

FullCalendarのimportは、FullCalendarを先に、プラグインのdayGridPluginはあとから読み込んでください。FullCalendarコンポーネントのpluginsにプラグインを配列要素として加えます。initialViewは、標準的な月単位のカレンダーdayGridMonthです(Docs / Month View参照)。

src/App.tsx
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid"; // pluginは、あとから

function App() {
  return (
    <div>
      <FullCalendar plugins={[dayGridPlugin]} initialView="dayGridMonth" />
    </div>
  );
}

export default App;

これで、月単位のカレンダーが表示されます(図001)。

図001■月単位のカレンダー

2106002_001.png

日本語表示にする ー localeの設定

FullCalendarコンポーネントにはlocaleが定められます。値を"ja"とすれば日本語表示です。

src/App.tsx
function App() {
  return (
    <div>
      <FullCalendar

        locale="ja"
      />
    </div>
  );
}

ところが、これだけでは完全な日本語表記にはなりません(図002)。

図002■ボタンが日本語表記にならない

2106002_002.png

公式ドキュメントの「locale」を読んでも、Reactの場合について具体的な説明がありませんでした。試行錯誤してみたところ、つぎのプラグインのインストールがいるようです。

npm install --save @fullcalendar/core

そのうえで、allLocalesimportして、localesに定めたところ、無事日本語表記にできました。

src/App.tsx
import allLocales from '@fullcalendar/core/locales-all';

function App() {
  return (
    <div>
      <FullCalendar

        locales={allLocales}
        locale="ja"
      />
    </div>
  );
}

予定を加える

カレンダーに予定を加えましょう。予定はオブジェクトにして、FullCalendarコンポーネントのeventsに配列で与えてください。基本的なプロパティとしては、イベント名のtitleと日時のdateです。日付のフォーマットは、文字列でYYYY-MM-DDとします。今月の文字列が得られるよう、関数(thisMonth())を加えました。

src/App.tsx
const thisMonth = () => {
  const today = new Date();
  return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(
    2,
    "0"
  )}`;
};
function App() {
  return (
    <div>
      <FullCalendar

        events={[
          { title: "event 1", date: `${thisMonth()}-01` },
          { title: "event 2", date: `${thisMonth()}-02` },
        ]}
      />
    </div>
  );
}

これで、ふたつの予定がカレンダーに加わります(図003)。

図003■ふたつの予定が加わった

2106002_003.png

クリックした日付を表示する

簡単なインタラクションを加えましょう。クリックしたら、その日付をダイアログで表示することにします。そのためには、プラグインをインストールしなければなりません。

npm install --save @fullcalendar/interaction

importしたinteractionPluginは、FullCalendarコンポーネントのpluginsに加えてください。用いるイベントはdateClickです。コールバックは、ReactのuseCallbackフックに定めた方がよいでしょう。ハンドラから受け取る引数(arg)は、プラグインから読み込んだDateClickArgで型づけします。これで、カレンダーのクリックした日付が、警告ダイアログで示されるはずです。

src/App.tsx
import { useCallback } from "react";

import interactionPlugin, { DateClickArg } from "@fullcalendar/interaction";

function App() {
  const handleDateClick = useCallback((arg: DateClickArg) => {
    alert(arg.dateStr);
  }, []);
  return (
    <div>
      <FullCalendar
        // plugins={[dayGridPlugin]}
        plugins={[dayGridPlugin, interactionPlugin]}

        dateClick={handleDateClick}
      />
    </div>
  );
}

書き上がったルートモジュールsrc/App.tsxの記述全体は、つぎのコード001のとおりです。具体的なコードの動きについては、冒頭のサンプル001をご参照ください。

コード001■ルートモジュール

src/App.tsx
import { useCallback } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import allLocales from '@fullcalendar/core/locales-all';
import interactionPlugin, { DateClickArg } from "@fullcalendar/interaction";
const thisMonth = () => {
  const today = new Date();
  return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(
    2,
    "0"
  )}`;
};
function App() {
  const handleDateClick = useCallback((arg: DateClickArg) => {
    alert(arg.dateStr);
  }, []);
  return (
    <div>
      <FullCalendar
        plugins={[dayGridPlugin, interactionPlugin]}
        initialView="dayGridMonth"
        locales={allLocales}
        locale="ja"
        events={[
          { title: "event 1", date: `${thisMonth()}-01` },
          { title: "event 2", date: `${thisMonth()}-02` },
        ]}
        dateClick={handleDateClick}
      />
    </div>
  );
}

export default App;

  1. 有償のプランも用意されており、追加のプラグインやサポートが提供されます。 

53
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
33