リアルタイム通知フィードの構築
SSEとReactのstateを組み合わせ、ユーザー操作なしでリアルタイムに更新される通知フィードを構築します。
「リアルタイム通知フィードの構築」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
通知フィードのアーキテクチャ
リアルタイム通知フィードは、受信通知用の SSE ストリームと、項目を既読にするための REST エンドポイントを組み合わせます。コンポーネントは通知リストをローカルステートで管理し、useEffect 内の EventSource を通じてサーバーストリームを購読し、ユーザー操作(既読化、非表示)には楽観的更新で対応します。
通知データの形式
通知オブジェクトは通常、次のような形式です。{ id: string, type: 'info' | 'warning' | 'success', message: string, timestamp: string, read: boolean }。type フィールドによってアイコンと色が決まります。read フィールドは、ユーザーが通知を確認済みかどうかを追跡します。timestamp によって時間帯別にグループ化できます。
SSE ストリームの購読
useEffect 内で /api/notifications/stream に接続する EventSource を作成します。各 message イベントで JSON を解析し、setNotifications(prev => [JSON.parse(e.data), ...prev]) のように新しい通知を state の先頭に追加します。先頭への追加(unshift と同じ動作)によって最新の通知が上に表示されるため、通知フィードでは一般的な方法です。
未読件数バッジ
追加の state を持たず、通知配列から未読件数を導出します。const unreadCount = notifications.filter(n => !n.read).length のように記述します。これを通知ベルアイコンのバッジとして表示します。通知の state が変わるたびに件数も自動的に更新されるため、別途 state を管理する必要はありません。
楽観的更新による既読化
ユーザーが通知をクリックしたら、まず楽観的に既読状態へ更新します。setNotifications(prev => prev.map(n => n.id === id ? { ...n, read: true } : n)) のように記述します。その後、バックグラウンドで /api/notifications/:id に { read: true } を付けて PATCH リクエストを送信します。リクエストが失敗した場合は、楽観的に行った更新をロールバックします。
時間別の通知グループ化
表示用に通知を「今日」(同じ暦日)、「昨日」、「それ以前」にグループ化します。通知の timestamp と現在の日付を使ってグループを計算します。const today = new Date().toDateString() のように記述します。各グループを見出しラベル付きの独立したセクションとして描画します。これにより、長い通知リストを簡単に確認できます。
バックグラウンド処理用のトースト通知
ユーザーが別のページを開いているときに SSE 経由で新しい通知が届いたら、通知リストを更新する代わりに、または更新に加えて、トーストを表示します。SSE の購読側とトーストの描画側の両方からアクセスできるグローバルな通知コンテキストまたは Zustand ストアを使用します。トーストは数秒後に消えますが、通知はリストに残ります。
グローバル通知コンテキスト
アプリ全体に表示する通知は、アプリのルートレベルにある React context または Zustand store に保存します。SSE の購読処理は、コンポーネントツリーの上部に近いプロバイダーコンポーネントに配置します。共有ストアを通じて、どのコンポーネントからでも通知を読み取ったり新しい通知を追加したりできるため、どのページからでもトーストを描画できます。
タブにフォーカスした際の SSE 再接続
EventSource はネットワーク切断時の再接続を自動的に処理しますが、タブの表示状態の変化は別の問題です。ユーザーが長時間離れた後にタブへ戻ると、SSE 接続がサーバーによって終了されている可能性があります。EventSource は自動的に再接続し、Last-Event-ID の仕組みによって、タブがバックグラウンドにある間にユーザーが見逃した通知を再送します。
ナビゲーション間での通知の保持
シングルページアプリケーションでは、ページを移動するとメモリ上の通知 state が失われます。更新のたびに通知を localStorage に保存します。localStorage.setItem('notifications', JSON.stringify(notifications)) のように記述します。マウント時には、SSE ストリームに接続する前に localStorage から state を初期化します。これにより、ページ移動後も通知履歴を保持できます。
SSE エンドポイントのパターン
サーバー側の SSE エンドポイントでは、特定のヘッダーを設定する必要があります。Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive です。Express/NestJS では、data: ${JSON.stringify(payload)}\n\n のようにイベントを書き込みます。イベントの終端を示す二重の改行に注意してください。ブラウザーがイベントをすぐに受信できるよう、サーバーは書き込みのたびに flush する必要があります。
SSE ストリームエンドポイントのパターン
SSE(Server-Sent Events)エンドポイントに設定する正しい Content-Type ヘッダーは何ですか?
レッスンのまとめ:リアルタイム通知フィード
通知フィードでは、SSE の購読(EventSource のクリーンアップを伴う useEffect)と REST による更新(既読化のための PATCH)を組み合わせます。データ形式は {id, type, message, timestamp, read} です。filter で unreadCount を導出し、表示時は今日、昨日、それ以前にグループ化します。ページをまたぐトーストにはグローバルコンテキストまたは Zustand を使用します。ナビゲーション後も状態を維持できるよう localStorage に保存します。SSE エンドポイントには Content-Type: text/event-stream、Cache-Control: no-cache、そして二重改行のイベント区切りが必要です。
よくある質問
「リアルタイム通知フィードの構築」レッスンは無料ですか?
はい。「リアルタイム通知フィードの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「リアルタイム通知フィードの構築」で何を学びますか?
SSEとReactのstateを組み合わせ、ユーザー操作なしでリアルタイムに更新される通知フィードを構築します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「リアルタイム通知フィードの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。