とある明確な1つの機能や用途を持っていたり、主に親コンポーネントのソースの見通しを良くするために機能や用途単位でコンポーネントとして切り出した、いわゆる「再利用性の低い」コンポーネントをtemplates
ディレクトリーに入れる。
templates
に入るようなコンポーネントは、どのページでのみ使うかが決まっている事がほとんどなので、templates
ディレクトリー内でさらにページ毎にディレクトリー分けしている。
templates
ディレクトリーに入るコンポーネントの実装が、parts
ディレクトリーに入っているコンポーネントのみで構成されているとは限らない。
- 例外を投げるのはAPIにリクエストを送るローレベルな箇所のみ。
try / catch
はユーザー操作由来のイベントハンドラーなど、1番上のハイレベルな層にのみ置く。つまり、処理の中間に位置するカスタムフック内の関数などはtry / catch
でラップしない。ただし、Spotifyのアクセストークンの更新などを担うuseSpotifyToken
では、例外的に関数をtry / catch
でラップして、直接エラーモーダルを表示している。
メインページ以外でusePlayerを利用する際、イベントリスナーが重複することによる二重処理などが行われないようにするため、引数には{initialize: false}
を渡すことになるが、initialize
がfalse
の場合、usePlayer配下のフック(例: useSpotifyPlayer)の引数も{initialize: false}
になるので、usePlayer配下のフックのuseEffectも作動しなくなり、再生位置の更新などがされなくなる。
ユーザーデーターの取得用にgetUserData
のような関数を用意すれば見た目は綺麗になるが、ユーザーデーターのRecoilStateがundefined
なのか(=Firestoreからのデーター取得が未完なのか)どうかの判定がややこしくなるので、ユーザーデーターの取得に関しては直接RecoilStateを参照するようにしている。
逆にuseEffectでRecoilStateを監視し、RecoilStateが更新されたらFirestore上のデーターも更新するという方法も思いつくが、setRecoilStateする時にユーザーデーターのundefinedチェックを挟まないとTypeScriptエラーが出てしまうのでコードが冗長に見えてしまう。データーの更新はワンライナーで済ませたいところ。
というような理由から、ユーザーデーターの取得・更新に関しては見出しのような仕様になっている。