【技育CAMP2024】ハッカソン Vol.12に参加してきました!!

記入日:2024/8/12 21:36:48

blog thumbnail

はじめに

【技育CAMP2024】ハッカソン Vol.12に即席チームとして参加してきました!!
今回は制作物やハッカソン中に躓いた点などをまとめていきます。

制作物

  • チーム名

    ランジャニーズ

  • 作品名

    ランジャニちゃん

  • 発表資料

    最初の制作物の案を出し合っている際に、「旅行したいけど特に行きたい場所がなく、そのまま旅行のタイミングを見失う」といった悩みを持ったメンバーがいたため、今回のハッカソンではその悩みを解決するような作品を作ることにしました。

    開発メンバーと技術スタック

    今回は即席メンバーということで現時点で触ったことのある技術を話し合い、フロントエンドとバックエンドに二人ずつ割り当て開発を進めました。私はフロントエンドを担当し、今まで触ってきたNext.js+TypeScriptを使用することにしました。Webデザインもフロント班の二人で進めることとなり、figmaを使用しました。

    使用したAPI

    • Google Map API

      座標から現在地を特定しマップに描画するために使用。

    • Geocoder API

      バックエンドからランダムに与えられる地名から座標を検索するために使用。ここで取得した座標をGoogle Map APIに渡しています。

    主に担当した箇所

    • Figmaを使用してページのレイアウト設計
    • TailwindCSSを使用してサイト全体の大まかなレイアウトの記述
    • 選ばれた地点のテキストをもとに座標を計算する機能の実装(Geocoder APIを使用)
    • 座標を下にMAPを描画する機能の実装(Google Map APIを使用)
    • サイト内の背景を変化させる機能の実装

躓いた点

開発中に躓いた点は以下の2点です。

  • MAPの読み込み
    import { LoadScript } from "@react-google-maps/api";
    
    ~~~
    省略           
    ~~~
    
                <LoadScript
                  googleMapsApiKey={
                    process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY ?? ""
                  }
                  libraries={["places"]}
                  loadingElement={<div>Loading...</div>}
                  onLoad={() => console.log("Google Maps script loaded")}
                  onError={(error) =>
                    console.error("Error loading Google Maps script", error)
                  }
                >
                  <Map address={address} />
                </LoadScript>

    Mapを読み込む際に上記のようにgoogle-mapから提供されているLoadScriptを使用していました。サーバー起動時はマップが描画されるものの、サインインページなどの別ページに遷移したあとに戻ってくるとマップが表示されないバグに直面しました。

    仕様をメンターさんと調べてみると「LoadScript がページ遷移前と後で二回スクリプトをロードしようとするのでエラーになってしまう」ことが分かりました。更に調べてみると、Reactを使用したMAPの表示を行っているリポジトリを発見し、以下のようにuseJsApiLoaderを使用する形に変更しました。

    import { useJsApiLoader } from "@react-google-maps/api";
    
    ~~~
    省略           
    ~~~
    
      const { isLoaded } = useJsApiLoader({
        id: "google-map-script",
        googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY ?? "",
      });
    
    ~~~
    省略           
    ~~~
    
    {isLoaded ? <Map address={address} /> : <div>Loading...</div>}

    上記のコードに変更後バグが解消されページ遷移後もマップが表示されるようになりました。

  • ウィンドウ幅の管理

    画面表示時のウィンドウサイズを取得し、useStateの初期値を設定したいと考え以下のようなコードを書きました。

    const [isMobile, setIsMobile] = useState(window.innerWidth <= 1024);

    すると以下のようなエラーが表示

    ⨯ src/components/Map.tsx (24:44) @ window
     ⨯ ReferenceError: window is not defined
        at Map (./src/components/Map.tsx:27:85)
    digest: "2479333777"
      22 |
      23 | function Map() {
    24 |   const [isMobile, setIsMobile] = useState(window.innerWidth <= 1024);
         |                                            ^
      25 |
      26 |   useEffect(() => {
      27 |     const handleResize = () => {
     GET / 500 in 30ms 

    調べてみると同じ問題を解決している記事を発見。どうやらNextJS は SSR を前提としているため、window を使おうとするとエラーになってしまうらしいです。Map.tsxでは先頭に"use client"をつけてCSRを宣言してるから大丈夫だと思っていたのですが引っかかっていたようです。記事を参考に以下のようなコードにすることでエラーが解消されました。

    const [isMobile, setIsMobile] = useState(false);
    
      useEffect(() => {
        setIsMobile(window.innerWidth <= 1024);
        const handleResize = () => {
          setIsMobile(window.innerWidth <= 1024);
        };
    
        window.addEventListener("resize", handleResize);
        return () => {
          window.removeEventListener("resize", handleResize);
        };
      }, []);

感想・反省点など…

学外のハッカソンの参加は初めてでしかも即席メンバーという事もあってものすごく不安と緊張を抱えて挑んだハッカソンでしたが、メンバーやメンターの協力もありなんとか発表まで頑張ることができました!!同じフロント班の方は今までHTMLやCSSを軽く触った位でフレームワークを何も知らない状態だったのにもかかわらず、今回最後までやり遂げてくれたのは本当に嬉しかったです。今まで技術を教えて貰う立場ばかりで人をリードする経験がなかったので、NextJSの説明や実装の役割分担などが大変でした(もう少し自分の知識があれば分かりやすく説明できたかな〜と若干後悔)。

あと、全体的なWebの知識が足りないなと感じることが多くありました。バックエンドの方たちと相談する際に、コードやターミナルを見せてもらうことや現在取り掛かっている作業の説明、データのやり取りの仕様決めなどの機会が何度かありました。相槌を打って聞いていたものの正直何を言っているか分からなかったことのほうが多く、開発が進むに連れフロントとバックの理解の齟齬が大きくなっていき最終日まで連携が取れずサーバーで動かせないといったことになってしまいました。ここは本当に反省していて、もっと準備期間に細かいところまで話して担当外のこともしっかり把握できるようにしておくべきでした。ハッカソン終了後の感想会でもメンバーから設計書や図をしっかりと定義しておくべきだったと意見が出ていたので今後のチーム開発では意識していきたいです。

賞は取れませんでしたが、即席チームで最後まで揉めずにやり遂げれたことは良い経験になったと思っています。私も含めて皆でゴールに向かって一週間走り切ることができました。楽しかったのはもちろんですがもっと知識をつけて強くならなくてはと思えるようなハッカソンだったので今後も頑張ります。