1
2

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】 #2 電波時計アプリを作成

Last updated at Posted at 2024-12-22

はじめに

現在、Reactを習得するために、23種類のReactアプリ開発に取り組んでいます。
今回はその第二弾として、Reactで電波時計アプリを作成しました。

要件

  • デジタル時計を画面上に表示すること
  • 日本標準時をサーバから取得して同期すること
  • 毎回フェッチするとパフォーマンスが低下するため、初回描画時のみ同期すること

作成したアプリのイメージ

アプリ紹介動画

利用技術

  • React
  • TypeScript
  • Vite
  • Tailwind

意識したポイント

useEffectでデータをフェッチ

初回レンダリング時に日本標準時をフェッチし、それを画面に表示する必要があるため、
useEffectを利用してデータを取得しています。
以降、1秒単位で時刻を更新するため、setIntervalを使用して時刻を加算しています。
コンポーネントがアンマウントされた後に実行されないように、
クリーンアップ関数でインターバルをクリアしています。

useServerTime.ts
const useServerTime = () => {
  const [myTime, setMyTime] = useState<Date | null>(null);
  useEffect(() => {
    const syncData = async () => {
      const time = await feachDateTime();
      if (time) {
        setMyTime(time);
      } else {
        console.error("サーバ同期に失敗しました。");
      }
    };

    syncData();

    const intervalId = setInterval(() => {
      setMyTime((prev) => {
        if (!prev) return new Date();
        return new Date(prev?.getTime() + 1000);
      });
    }, 1000);

    return () => {
      clearInterval(intervalId);
    };
  }, []);

  return myTime;
};

今回は初回レンダリング時にのみフェッチするので依存配列は空です。

日本標準時を「World Time API」を介して取得

日本標準時は「World Time API」を使ってインターネットから取得しています。
「World Time API」は、特定のタイムゾーンの現在時刻を取得できるシンプルなWebAPIで、
インストール不要で使用することができます。
APIからデータを取得し、日付をDateオブジェクトに変換して表示しています。

fetchTime.ts
const feachDateTime = async (): Promise<Date | null> => {
  try {
    const res = await fetch("http://worldtimeapi.org/api/timezone/Asia/Tokyo");
    if (res.ok) {
      const data = await res.json();
      const datetime = new Date(data.datetime);
      console.log(`サーバ同期に成功:${datetime}`);
      return datetime;
    } else {
      console.error(`サーバ同期に失敗しました status:${res.status}`);
      return null;
    }
  } catch (error) {
    console.error(error);
    return null;
  }
};

World Time APIの詳細はこちらから確認できます:
https://worldtimeapi.org/

カスタムhooksに分割して実装

データフェッチ部分は別のAPIファイルに、
useEffectでのレンダリング部分はカスタムフックとして分割しました。
このようにすることで、デジタル時計の描画部分をシンプルに保つことができました。

おわりに

今回は、useEffectとカスタムコンポーネントへの分割を意識して実装を行いました。
コードの可読性や再利用性を高めるために、関心ごとを分けてシンプルに保つよう意識して実装できたのが良かったです。

Github

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?