React × Chakra UI × Supabase × TypeScriptで学習記録アプリを作ってみた
はじめに
今回は、React × Chakra UI × Supabase × TypeScript を使って学習記録アプリを開発しました。
最初は簡単に作れると思っていたのですが、実際には予想以上にハマるポイントが多かったです。
特に、UIライブラリのバージョン問題やモーダルの状態管理、データの自動更新あたりで苦戦しました。
開発したアプリの概要
実装した機能
- 学習内容と学習時間の記録
- 記録の一覧表示(ページネーション付き)
- 記録の編集・削除
- 全角数字の自動変換
- フォームバリデーション
開発技術
技術 | バージョン | 説明 |
---|---|---|
React | 18.3.1 | コンポーネント単位でUIを構築できるJavaScriptライブラリ。 |
Chakra UI | 2.8.2 | カスタマイズ性の高いReact向けUIライブラリ。 |
Supabase | 2.46.2 | BaaS(Backend as a Service) |
TypeScript | 5.6.2 | 型安全を強化し、バグを減らせるJavaScriptの拡張言語。 |
Vite | 6.0.1 | 高速な開発環境とビルド機能を備えたフロントエンドツール。 |
開発中に直面した課題とその解決策
① Chakra UI v3からv2への"逆"移行
開発当初は Chakra UI v3 がリリースされたタイミングと被ったため、v3を採用しました。
しかし、以下の問題に直面しました。
- ドキュメントの内容と実際の挙動が違う
- エラーが出てもググっても情報が少ない
- 他のライブラリとの相性が微妙
バージョンが新しいため解決方法の情報量が足りず、自分の力量では直面した問題を解決することができませんでした。
解決方法
そこで、安定性と情報量を考えて、Chakra UI v2にダウングレード しました。
- v2なら公式ドキュメントが充実している
- QiitaやGitHubにもサンプルコードが多い
- 予期せぬエラーに悩む時間を減らせる
結果的に、開発がスムーズになりました。
② モーダルとフォームの連携
モーダル内でフォームを扱うときに、状態管理が意外と難しいことに気づきました。
- モーダルを開いたときに前のデータが残る
- 編集時の初期値を正しくセットできない
- バリデーションエラーの挙動が不安定
解決方法
useForm
の reset
と useEffect
を活用し、モーダルを開くたびにフォームをリセットする仕組みにしました。
useEffect(() => {
if (study && open) {
reset({
learn_title: study.learn_title,
learn_time: study.learn_time,
});
}
}, [study, open, reset]);
これにより、編集時の初期値設定やバリデーションエラーの問題が解消されました。
状態管理の重要性を改めて実感しました。
③ Supabaseでの更新日管理
Supabaseを使ってデータを管理していましたが、「更新したら 更新時間:updated_at
も自動更新されるようにしたい」と思いました。
これは単に更新日時を記録するためではなく、「最新のデータをソートして表示したい」 という理由もありました。
例えば、学習記録を一覧表示するときに、新しく編集したデータを上位に表示 したかったのですが、updated_at
が自動更新されないと、どのデータが最近変更されたのか分かりません。
解決方法
Supabaseのトリガー機能を使い、データが更新されたら updated_at
も自動更新されるようにしました。
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER handle_updated_at
BEFORE UPDATE ON study_record
FOR EACH ROW
EXECUTE FUNCTION update_modified_column();
このトリガーを設定することで、レコードが更新されるたびに updated_at が自動で更新 されるようになりました。
これにより、フロントエンド側で updated_at を意識しなくても、最新のデータを自動的に上位に表示 できるようになりました。
成長したこと & 気づき
①コンポーネント設計を意識できるようになった
以前は「とりあえず動けばいい」という作り方をしていましたが、今回は再利用性を意識して設計できるようになりました。
②状態管理の理解が深まった
「どのコンポーネントがどの状態を持つべきか」を意識できるようになり、無駄なリレンダリングを減らせるようになりました。
③データベース側で処理できるものはDBに任せるべき
Supabaseのトリガーを活用することで、フロントエンド側の実装を減らせることを学びました。
おわりに
今回のアプリ開発を通して、「実装力」だけでなく「設計力」も鍛えられたと感じています。
特に、状態管理やデータ管理の重要性を改めて実感しました。
今後も試行錯誤しながら開発を続け、より良い設計を学んでいきたいと思います。
✅JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼