3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go × ReactでSSEを実現する(Step2:Reactでリアルタイム受信)

3
Posted at

はじめに

前回までに、Goを使って「2秒おきにメッセージを送り続けるサーバー」を作りました。

今回はStep 2として、そのデータをReact側で受け取って画面に表示させてみます。

「ライブラリは何を使うの?」と思うかもしれませんが、実はSSEはブラウザ標準の機能だけで実装できちゃいます。余計なインストールなしでサクッと作っていきましょう。


SSE実装の全体ロードマップ

  1. Step 1:Goで最小限のSSEサーバーを作る(完了!)
  2. 【本記事】Step 2:Reactでシグナルの受信を実装する
  3. Step 3:GoでHub(配信所)を設計し、一斉送信を可能にする
  4. Step 4:API送信と連携し、実用的なチャット基盤を完成させる

今回のゴール:最小構成の受信機を作る

動作デモ

sse_step2.gif

画面のデザインは一切気にせず、「サーバーから届いた文字列をそのままリストに表示する」という最小構成のコンポーネントを作ります。


1. フロントエンドの準備

まずはViteを使ってReact(TypeScript)プロジェクトを立ち上げます。
(バックエンドのディレクトリの隣に作る想定です)

npm create vite@latest frontend -- --template react-ts
cd frontend
npm install

2. ReactでSSEを受け取る

src/App.tsx を以下のコードに書き換えます。
ブラウザ標準の EventSource というAPIを使うのが一番のポイントです。

import { useEffect, useState } from 'react'

function App() {
  const [messages, setMessages] = useState<string[]>([])

  useEffect(() => {
    // 1. Step 1で作ったGoのサーバーにSSE接続を開始
    const eventSource = new EventSource('http://localhost:8080/events')

    // 2. サーバーからメッセージ(data)が届いた時の処理
    eventSource.onmessage = (event) => {
      console.log('New data:', event.data)
      // 届いたデータを配列に追加
      setMessages((prev) => [...prev, event.data])
    }

    // エラー(接続切れなど)が起きた時の処理
    eventSource.onerror = (err) => {
      console.error('SSE Error:', err)
    }

    // 3. クリーンアップ処理
    // これを忘れると画面遷移のたびにコネクションが増えてしまうので注意!
    return () => {
      eventSource.close()
    }
  }, [])

  return (
    <div style={{ padding: '20px' }}>
      <h1>SSE Receiver</h1>
      <p>Goのサーバーから届いたデータが表示されます:</p>
      <ul>
        {messages.map((msg, i) => (
          <li key={i}>{msg}</li>
        ))}
      </ul>
    </div>
  )
}

export default App

実装のポイント

  • useEffectで接続: コンポーネントが読み込まれたタイミングで接続を開始します。
  • 自動再接続: EventSource は優秀で、もしネットワークが一時的に切れても、ブラウザが勝手に再接続を試みてくれます。自分でリトライ処理を書かなくていいのが最高ですね。
  • 最後は必ずclose(): return () => eventSource.close() を書かないと、開発中のホットリロードなどで接続がどんどん増えてサーバーがパンクするので、ここは必須です。

3. 実際に動かしてみる

手順 1: バックエンドを起動
前回のディレクトリに移動して、Dockerを立ち上げておきます。

docker compose up

手順 2: フロントエンドを起動
別のターミナルでReactを起動します。

npm run dev

手順 3: ブラウザで確認
表示されたURL(http://localhost:5173 など)を開いてみてください。
2秒おきに {"time": "...", "message": "Ping!"} という文字列がポコポコ増えていけば大成功です!


おわりに

これで「サーバーから送られたものをReactで表示する」というパイプラインが繋がりました!

今は「全ユーザーに同じタイミングで2秒おきに送る」という一方的な仕組みですが、次回のStep 3では、Goの channel を使って「誰かが発言した時だけ、接続中の全員に通知を飛ばす」という、よりチャットに近い「配信所(Hub)」の仕組みを作っていきます!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?