現役高校生が水泳記録管理サービスを作った話/その2：フロントエンド編


# はじめに

この記事は、Qiita Advent Calendar 3日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9

# 筆者について

- 現在高校２年生
- 水泳部マネージャー
- 生徒会長
- とある団体の代表

# 本編

## 構想段階

### 技術選定

この構想段階では、以下のような要件を定めました。

- できるだけ楽に書ける技術
- カスタマイズ性に長けてる
- モバイルデバイスにも対応できるフレームワーク
- まあまあ楽にスタイルシートをかける仕組み

### 悩むに悩む

最初のこの段階ではバニラHTMLとバニラCSSを描く気満々でした。というのも今までReactとかNextとかVueとか使ったことがかなったので、これを新たに学ぶよりは楽やろうとかいう甘い考えをしていたのですが、調べるうちにそんなアホみたいなことをするのは時間をドブに捨てるに等しいってことが判明したので、フロントエンドは仕方なく新しくフレームワーク勉強するか〜って感じでした。ここででできた候補は以下の通りです。

#### React

Meta社が開発しているオープンソースフレームワーク

https://ja.react.dev/

#### Vue.js

尤雨溪が開発したフレームワーク

https://ja.vuejs.org/

#### AnlarJS

Googleが中心となって開発しているフレームワーク

https://angularjs.org/

#### Next.js

Reactベースのフレームワーク

Vercelが中心となって開発しているフレームワーク

https://nextjs.org/

### 最終的に

最終的に選ばれたのは…Reactでした！

https://ja.react.dev/

ちなみにReactを採用した理由は以下の通りです。

- Nextは機能がありすぎてよくわからん
- なんかVueとどっちの方が描きやすいってなったらReactの方が見た目かきやすかった
- Angularはななんかサポートが終わってるとか終わってないとか

また、CSSにはBootstrapを利用しました！これは非常に楽ちん！！

https://getbootstrap.jp/


## 開発スタート！

フロントエンドの処理は案外簡単でした〜！
というてもつまずきだらけではありましたが、、、。

### 認証回りどうするねん問題

基本的には必要なところに以下のコードを記述しました。

```javascript:frontend.js
import 'firebase/compat/auth'
import firebase from 'firebase/compat/app'
import { getAuth, onAuthStateChanged } from 'firebase/auth';

function checkAuthUser() {
  const [idToken, setIdToken] = useState();
  useEffect(() => {
    const getIdToken = async() =>{
        const firebaseConfig = {
            apiKey: process.env.REACT_APP_FIREBASE_APIKEY,
            authDomain: process.env.REACT_APP_FIREBASE_AUTHDOMAIN,
            projectId: process.env.REACT_APP_FIREBASE_PROJECTID,
            storageBucket: process.env.REACT_APP_FIREBASE_STORAGEBUCKET,
            messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGEINGSENDERID,
            appId: process.env.REACT_APP_FIREBASE_APPID,
        };
        const init = firebase.initializeApp(firebaseConfig);
        const auth = getAuth(init);
        const idToken =await getIdToken((await firebase.auth().onAuthStateChanged());
      }
    }
  )
}
```

んでここの問題は、```useState()```です。実は開発している時に値管理のほとんどに```useState()```を利用していたのですが…。これが多すぎるとエラーがでるんですよね。つまりuseEffectを減らす方法を考えないといけないのですが、以下の選択肢になりました。

- ```useMemo()```の利用
- Reduxの利用
- データの配列化

#### ```useMemo()```の利用

```useMemo()```の利用は諦めました。というのも、セキュリティ的にログアウトされている状態ではログアウトに促すダイアログを表示させたいので、結果が変わるたびに描画を変えることができる```ussState()```にはかないませんでした。

#### Reduxの利用

Reduxについては以下のホームページより

https://redux.js.org/

簡単に説明すると、アプリケーション全体で値を管理することができるライブラリです。ですがこれは一番ナシな選択肢でした。

- 学習コストが高すぎる
- ```getIdToken()```がどのタイミングで切れるかもわからないから使えない
- 他のプラットフォームに移植するときにどうするねん、的な

これらの理由からなしという選択肢になりました。

#### 値の配列化

これを最終的には利用しました。値を配列化するものです。例えば、Aという値とBという値を同時に管理したいと思います。

```javascript:pg01.js
function pgp1(){
  const [a, setA] = useState();
  const [b, setB] = useState();
}
```

しかしこれでは```useState()```の使いすぎだというエラーが出ました。というときには、以下の通りに値を書き換えましょう。

```javascript:pg02.js
function pgp2(){
  const [c, setC] = useState(["a","b"]);
  //aの値が変わるとき
  setC([newA, c[1]]);
  //bの値が変わるとき
  setC([c[0],newB]);
}
```

少々複雑な仕組みではありますが、これで多すぎるというエラーは出なくなります。

### 見た目

センスのない僕にとって一番でかい問題でした。以下のような要件を定めました。

- コンソール的な見た目
- 青のイメージを利用するけどシンプルなマテリアル的なイメージがいい

Naterial Designについては以下のリンクを参考にしてください。

https://m3.material.io/

ここで頭の思い浮かんだのが、「これ、Google系のサービスを参考にしたらいいんじゃね？」って。

![Google Drive イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/cfd90579-9cca-f7ad-eaf4-2eb288395ba4.png)

ということで、Google Driveのこの画面を分析して以下のような特徴をつかみました。

- [^1]ベースカラーになる一色と白での構成になっている
- ベースカラーは固定部分に、白い部分は変動部分に配色されている
- 左にメニューの配置
- 右上にアイコンが配置されている

これらの個人的「見やすいって思った特徴」と、個人的に読んだ書籍で描かれれていた文言を元にデザインを行いました。
それが以下の通りとなります。

![SOKFI 画面イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/389d9e35-9920-d09e-0b4e-7d9627d66076.png)

ちょっとめんどくさいのはGoogle Driveと違ってベースカラーが濃いことですね。けど、まあまあええ感じに持って行けたんではないでしょうか。

### 認証何使う問題

Firebase Authenticationではさまざまなログイン手段が用意されています。

https://firebase.google.com/docs/auth?hl=ja

けどここでどの手段を利用するか、かなり悩みました。

- お金はかけない
- 学生も利用しているものには対応したい

この条件に合うものが、GoogleとMicrosoftという結論にいたりました。おそらく教育現場にもよく使われているログイン手段ではないでしょうか。
（ちなみに、テスト時に採用したGitHubとYahooも一応そのまま入れてます。）

# 最後に

バックエンドでえらい苦労していますが、フロントエンドはまあまあすらっとかけました。大詰めとなってきましたがこの後どのような道を辿ることになるのでしょうか。今後のアドカレ 23 の記事をお楽しみにしてください。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9

[^1]: この後の今後の展望編でも記述するつもりですが、今後他にもさまざまな形でこのSOKFIを利用していきたいと思っており、その時にベースカラーひとつで違う種類のものだと認識できる上に統一感を出せるようなデザインにしたかったっていうのも理由の一つです。