4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Reactアプリ100本ノック 08 Calendar】をやってみて

Last updated at Posted at 2024-01-24

はじめに

今回こちらを行ってみました。100本ノックなんて考えるのも大変なのに、それを無料でこういったハンズオン?力試し?的なものを提供して下さるなんて尊敬しかありません。

筆者は普段Reactで、業務においてはサイト制作や、プライベートでは(変な)個人開発ばかりしているので、カレンダーアプリなんて実用的なものを作る経験はあまりありませんでした。ですから今回すごく勉強になったと感謝しています。

少し前置きが長くなりましたが筆者が制作したものを貼っておきます。

https:// benjuwan-react-calendar.netlify.app/

本記事のカレンダー機能を含んだ個人開発を行ったため上記ページは閉鎖しました。関心を持って下さった方は是非こちらの記事をご覧ください。

benjuwan-react-calendar.gif

  • 利用技術
    • React
    • TypeScript
    • vite
    • Jotai(ToDoメモリストとlocalstorageの中身をグローバルステートとして管理)
    • CSS Modules

普段はstyled-componentsを使っているのですが先日Next.jsを触った際に(サーバーコンポーネントでは)styled-componentsを使えないことを知りまして、CSS Modulesに慣れておこうと初めて使ってみました。
元記事にあったライブラリdate-fnsは使いませんでした(使いこなせませんでした)

概要

今回のノックの達成条件は以下でした。

  • カレンダーが表示されている
  • 土日は赤色で表示する
  • 前の月、次の月をページネーションできる
  • 日付に対して予定を複数追加できる
  • 予定の編集削除ができる

達成条件に対するアプローチ

カレンダーが表示されている

初っ端のここで躓きました。元記事にあったライブラリdate-fnsのドキュメントを見てもいまいちうまくいかず(スキル不足!)、結局Chat-GPTにヒントをもらいました。
生成AIについては色々な意見がありますが、個人的には筆者のように独学スタイルな人間には非常に有難い存在です。壁打ち相手にもそうですが、自身の解釈が合っているかどうかの確認などにも有用なので重宝しています。

土日は赤色で表示する

土日どちらも赤色だと分かりづらいかもと思って筆者は土曜日は青色、日曜日は赤色にしました。
土日の判定はカスタムデータ属性を使用しました。

.
..
<li key={i} data-daydate={day.dayDateNum} className=......>
..
.

具体的にはdata-daydate={day.dayDateNum}の部分でCSSのスタイルを書き分けています。

/* 日曜日 */
[data-daydate='0'] {
    background-color: #f5c0c0;
}

/* 土曜日 */
[data-daydate='6'] {
    background-color: #f5c0c0;
}

前の月、次の月をページネーションできる

ここは素直に「年」や「月」のstateを用意して対応。
しかし、手元のiPhoneやPCのカレンダーを見てみると先月の最終週と来月の初週の一部が当月と一緒に表示されていることに気づき『確かにその方が分かりやすいかも』と同じような見た目にすることにしました。

スクリーンショット 2024-01-24 165016.png

先月と来月の部分に関しては「月数を表示」+「スケジュール登録機能無し」を行って当月分との差別化を図っています。

日付に対して予定を複数追加できる

複数予定に関しては、配列形式のstateを用意して入力した内容を随時追加していく方法を採りました。
ただ進める中で『時間も入力できたほうが便利そうだ』と思って開始時刻・終了時刻の項目も追加しています。

スクリーンショット 2024-01-24 162740.png

予定の編集削除ができる

筆者の場合は以下のような型のオブジェクトとしてToDoメモを管理。

export type todoItemType = {
    todoID: string;
    todoContent: string;
    startTime?: string;
    finishTime?: string;
    edit: boolean;
}

この型に則ったオブジェクトを先ほど話したように配列形式のstateとして取り回して「編集」や「ToDoの中身(内容と時刻)」を扱うようにしました。

編集したい場合はedittrueにして「見た目(表示)の変更」と「オブジェクトの登録機能 → 更新機能への切替」を行い、再登録できるようにしています。

スクリーンショット 2024-01-24 162937.png

ToDoメモを押下すると詳細画面が開き、

スクリーンショット 2024-01-24 163026.png

この画面で編集します(「削除」を押下すると当該ToDoメモが消えます)

スクリーンショット 2024-01-24 163037.png

編集・削除機能に関しては、シャローコピーしたオブジェクトにspliceメソッドを使って、それをセッター関数に指定してstateを更新しています。

詰まったところ

先月・来月へのカレンダー移動時に前月で入力した内容が次月の同じ場所に反映されるという事態が起きました。
結論から言うと、これはToDoメモを管理しているstateを初期化していないために起きたことでした。かなり初歩的で恥ずかしいのですが結構時間を食って最終的にChat-GPTに泣きつくという情けなさでした。
『ここでこの実装をしているから、あーでこーで』と色々関係ないところを怪しんだりして……。そもそもシンプルで可読性の高いコードを書けていれば、このような初歩的なミスに気づけたと思いますので猛省です。

自分で追加した機能

localstorageを使っているので同ブラウザであれば、ご自身が入力されたスケジュールは保持されたままになります。
地味にこの機能を追加するのが面倒だったので何か楽なライブラリあればなぁとか思っています。
筆者がうまくそのライブラリを使いこなせるかの問題がありますが……。

さいごに

ここまで読んでいただき、ありがとうございました。
冒頭にも書きましたが、こういった企画を行い、ハンズオンを提供できるほどのスキル・知見は素晴らしいと思います。筆者もぜひ獲得したいものです。今後も興味のあるものがあれば折を見てまたチャレンジできればと思います。

今回制作した内容のGitHubを下記に置いておきますので関心のある方はご自由にしてください。

4
2
1

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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?