171
102

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/Supabase】

Last updated at Posted at 2025-11-02

はじめに

お疲れ様です。
今回の課題では、「Study Spot Vancouver」 という自習スポット検索アプリを開発しました。
React・TypeScript・Supabase・Google Maps API・Chakra UIを使用し、
地図上にピンを表示 → 条件で絞り込み → 詳細ページに遷移できる仕組みを実装しました。

この課題では、API連携・状態管理・UI設計の流れを一通り経験でき、
「地図アプリが動くまでの仕組み」を深く理解する良い機会になりました。

アプリ作成理由

  • 個人的な課題の解決
    バンクーバーで自習できる場所を探すとき、
    Google Mapsでは「カフェ」「図書館」など大まかなカテゴリしかわかりません。

しかし、実際に自習する上で重要なのは、静かさ・電源の有無・Wi-Fiの有無など
といった現地でしかわからない情報です。

特に、英語の音読やプレゼン練習など「声を出して勉強できる場所」は情報がほとんどなく、その都度現地で確認する必要がありました。

この不便を解消するために、「自習条件で検索できる地図アプリ」 を作ろうと考えました。

アプリ概要

GitHubリポジトリ:
https://github.com/kazukashima/kadai5.git

このアプリでは、Vancouver市内の自習スポットを地図上に表示し、
WiFi・電源・声出しOKの有無で簡単に絞り込みできるようになっています。

また、以下のMVPを自ら設定し、それに従い実装しました。

  • MVP1 React + TypeScript + Vite で開発環境構築。Firebase Hosting へデプロイ。make deploy による自動化。
  • MVP2 GitHub Actions で CI/CD を構築。push 時に自動テストと自動デプロイを実行。
  • MVP3 Google Maps APIを導入し、Supabaseから取得したデータをピンとして地図上に表示。
  • MVP4 Wi-Fi / 電源 / 声出しOK で絞り込みできるフィルター機能を実装。
  • MVP5 ピンをクリックすると詳細ページに遷移し、写真・住所・営業時間を表示。Google Mapsで開くリンクを設置。

ホーム画面

スクリーンショット 2025-10-28 002647.png

地図表示

左上の WiFi・Power・Talking の各ボタンを切り替えることで、
それぞれのスポットが WiFiを利用できるか、電源があるか、私語(声出し)が可能か を条件に絞り込みできます。
スクリーンショット 2025-10-28 002811.png

マップ動作デモ

地図上のピンをクリックすると、
施設名と「WiFi・電源・声出しOK」などの基本情報がポップアップ表示されます。
「詳細を見る」ボタンを押すと、
そのスポットの詳細ページへ遷移し、住所や写真などの情報を確認できます。
詳細ページの 「開く」リンク から、
実際のGoogleマップを開いてルート検索や周辺確認も可能です。

Map Demo

データの収集方法

自習スポットの情報は、実際に訪れて確認しました。
たとえば、「WiFiの有無」「電源の有無」「声を出して勉強できるか」などは
ネット上では分からないため、現地に行ってスタッフに直接聞いたり、
自分で勉強してみて雰囲気を確かめたりしました。

行けなかった施設については、メールで問い合わせを行い、
正確な情報を得るように心がけました。

使用した技術

分類 使用技術 / 内容
フロントエンド React + TypeScript + Vite
UIライブラリ Chakra UI(トグルボタン・レスポンシブデザイン)
データベース Supabase(自習スポット情報をクラウド管理)
マップ描画 Google Maps API(@vis.gl/react-google-maps)を使用してピンを表示
デプロイ Firebase Hosting(本番環境に自動反映)
CI/CD GitHub Actions(push 時にテスト & 自動デプロイ)
自動化 Makefile(make deploy / make test で簡易実行)

アーキテクチャ図

image.png


開発で苦労したポイントと解決策

1. Google Maps API と React の再レンダー問題

Reactの再レンダーが発生しても、Google Maps側の表示が更新されず、
フィルターを切り替えてもピンが変わらない問題がありました。

原因は、ReactのVirtual DOMとGoogle Mapsの描画が別システムで動いていることにありました。
解決策として、<Map key={JSON.stringify(filters)}> のように
keyを変更して再描画する方法を採用しました。

<Map key={JSON.stringify(filters)} ... >

2.フィルターの状態管理(boolean型の扱い)

3つの条件(WiFi・電源・声出しOK)を切り替える際、
useStateでまとめて管理し、動的に更新できるようにしました。

const [filters, setFilters] = useState({
  wifi: false,
  power: false,
  talking: false,
});

ボタンを押すたびにtoggleFiltersで特定のキーだけ反転させることで、
複数条件を簡潔に切り替えられるようにしました。

3.詳細ページ遷移とGoogleマップリンク生成

地図上のピンをクリックしたときに詳細ページへ遷移し、そのページで「Googleマップで開く」リンクを動的に生成しました。

<a
  href={`https://www.google.com/maps?q=${spot.latitude},${spot.longitude}`}
  target="_blank"
  rel="noopener noreferrer"
>
  Google Mapsで開く
</a>

テンプレートリテラル(...)を使うことで
緯度・経度から動的にURLを組み立てられることを学びました。

成長したポイント・学び

1. 外部APIとの連携力がついた

Google Maps APIやSupabaseなど、外部サービスを自分のアプリに統合する流れを実体験できました。
APIキーの管理・非同期処理・環境変数の扱いなどを理解できたのが大きな収穫です。

2. データ構造を意識して設計できるようになった

Supabaseのテーブル設計(id, name, latitude, longitude, wifi, power, talking)をUIの動きと合わせて考えたことで、データとUIの関係性を意識する力が身につきました。

3.状態と描画の関係を理解した

フィルター切り替え時にピンが更新されない問題を通して、
Reactの再レンダーと外部ライブラリ(Google Maps)の描画が別で動いていることを学びました。


感想・おわりに

まだUI/UXの改善や、Supabaseへのデータ追加など課題は残っています。
しかし、自分でMVPを設計し、段階的にアプリを完成させた経験を通じて、
“目的を持って開発を進める力” が身についたと感じています。

今後は、さらにデータを増やし、UI/UXを改善して、
「実際に価値を提供できるアプリ」へと成長させていきたいです。


JISOUでは仲間を募集中!
日本一のアウトプットコミュニティで、あなたも一緒に成長しませんか?
https://projisou.jp/

171
102
2

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
171
102

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?