0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

YouTube連動ポモドーロタイマー『TubePomo』のコンポーネント構成

0
Last updated at Posted at 2026-09-13

はじめに

先日、noteで 「YouTube連動のポモドーロタイマーアプリ『TubePomo』」 の開発ストーリーと概要を紹介しました。

📝 前回のnote記事はこちら

前回の記事では、アプリのコンセプトや開発の背景、そして「こだわった実装ポイント」として

  • YouTubeのURLから動画・再生リストIDを抽出する処理
  • 設定をLocalStorageと同期するカスタムフック

の2点を簡単に紹介し、「技術的な詳細は別記事で」とお伝えしていました。今回はその続編として、TubePomoのコンポーネント構成をもう少し技術寄りに掘り下げてまとめます。

アプリ概要

YouTubeの音楽と連動して動くポモドーロタイマーアプリ「TubePomo」を作りました。集中時間と休憩時間でそれぞれ別のプレイリストを再生できるのが特徴です。

今回は、このアプリのコンポーネント構成を簡単にまとめてみます。

コンポーネント構成

見やすさのため、「①画面コンポーネントの階層」と「②hooks・utilsとの依存関係」を、どちらも箇条書き・表で掲載します。

①コンポーネントの階層

App.jsx を頂点に、各画面パーツがどうぶら下がっているかを示すと以下のようになります。

  • App.jsx(状態管理の中心)
    • Timer.jsx
    • Player.jsx
      • PlayerSizeControls.jsx
    • PlaylistForm.jsx
    • TrackList.jsx

App.jsx がタイマー設定・曲リスト・再生位置などすべての状態を持つ中心的な存在で、各コンポーネントはそこから props を受け取って表示・操作する役割に徹しています。PlayerSizeControls.jsx だけは Player.jsx の子コンポーネントとして、プレイヤーの表示サイズ切り替えを担当しています。

②hooks・utilsとの依存関係

各コンポーネントがどの hooks / utils を使っているかを、表にまとめました。

呼び出し元 使用している hooks / utils
App.jsx useTimer.js、useLocalStorage.js、constants.js、playlist.js、timerSettings.js、youtubeErrors.js
Timer.jsx formatTime.js
Player.jsx playerLayout.js
PlaylistForm.jsx youtube.js
TrackList.jsx youtube.js

各ファイルの役割 簡易まとめ

components(画面に表示されるパーツ)

ファイル 役割
Timer.jsx 集中/休憩の残り時間表示、スタート・一時停止・リセット、分数設定の入力欄
Player.jsx YouTube IFrame Player(react-youtube)のラッパー。再生/一時停止・音量・サイズ切り替え・エラー通知を担当
PlayerSizeControls.jsx プレイヤー表示サイズ(小・中・大)を切り替える3ボタンのセグメントコントロール
PlaylistForm.jsx YouTubeのURLを入力して曲・プレイリストを追加するフォーム
TrackList.jsx 登録済みの曲一覧の表示、削除、並び替え(Top/↑/↓/Bottom)UI

hooks(状態ロジックの分離)

ファイル 役割
useTimer.js 集中/休憩モードのカウントダウンと切り替えだけを管理するカスタムフック。YouTube側のことは一切知らない
useLocalStorage.js useState と LocalStorage を同期させる汎用フック。設定や曲リストの永続化に使用

utils(純粋関数・定数)

ファイル 役割
constants.js LocalStorageのキー、デフォルト設定、タイマーの分数の上限/下限、プレイヤーサイズなどの定数をまとめる場所
playlist.js 曲リストから再生対象を取り出す・並び替えるなどの配列操作関数
playerLayout.js 画面サイズから、プレイヤーの表示サイズ(小・中・大)ごとの幅・高さを計算する
youtubeErrors.js YouTube Player のエラーコードをメッセージに変換し、再生エラー時のリトライ上限を算出する
youtube.js YouTubeのURLから動画IDやプレイリストIDを抽出・検証する
formatTime.js 秒数を MM:SS 形式の文字列に変換する
timerSettings.js タイマーの分数設定を1〜90分の範囲に収める

設計で意識したこと

コンポーネント構成を考える上で、次の3点を意識しました。

  1. 状態は App.jsx に集約する
    タイマーの状態や曲リストなど、複数のコンポーネントから参照される情報は App.jsx にまとめ、各コンポーネントは props 経由で受け取って表示・操作するだけにしています。状態がどこにあるか迷わないようにするためです。
  2. hooks でロジックを分離する
    useTimer はタイマーのカウントダウンだけ、useLocalStorage は永続化だけ、というように役割を1つに絞ったカスタムフックとして切り出しています。前回のnote記事で紹介した「設定をLocalStorageに保存する処理」も、この useLocalStorage.js として実装しています。
  3. utils は副作用のない純粋関数にする
    youtube.js(URL解析)や formatTime.js(時間のフォーマット)など、入力に対して同じ出力を返すだけの関数として切り出すことで、テストや再利用がしやすい形にしています。

まとめ

  • 状態は App.jsx に集約し、各コンポーネントは props 経由で受け取って表示するだけにする
  • hooks でロジックを分離(useTimer はタイマー、useLocalStorage は永続化)することで、コンポーネント側をシンプルに保つ
  • utils は副作用のない純粋関数として切り出し、テストや再利用がしやすい形にする

役割ごとにファイルを分けておくと、後から機能を追加するときにも「どこを触ればいいか」がすぐわかるので、個人開発でも保守しやすいと感じました。

アプリ自体は下記から無料で試せますので、よければ触ってみてください。フィードバックもお待ちしています。

🔗 https://takato0718.github.io/pomodoro/


0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?