React Academy · レッスン

再接続、エラー処理、クリーンアップ

切断を適切に処理し、useEffect内でsocket listenersをクリーンアップします。

レッスン 4/413 ステップ

「再接続、エラー処理、クリーンアップ」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

再接続が重要な理由

モバイルではネットワークの中断がよく起こります。再接続のロジックがないと、ユーザーはリアルタイム接続を気づかないまま失います。適切な方法では、バックオフを使って自動的に再試行します。

Socket.IO の自動再接続

Socket.IO はデフォルトで自動的に再接続します。io() のオプションで reconnectionAttempts、reconnectionDelay、reconnectionDelayMax を設定します。

const socket = io('https://api.example.com', {
  reconnectionAttempts: 5,
  reconnectionDelay: 1000,       // initial delay
  reconnectionDelayMax: 10000,   // max delay (exponential backoff)
  randomizationFactor: 0.5,
});

React での接続状態の追跡

connect、disconnect、connect_error イベントをリッスンし、コンポーネントの状態にステータスを反映します。

function useConnectionStatus() {
  const [status, setStatus] = useState<'connected' | 'disconnected' | 'error'>(
    socket.connected ? 'connected' : 'disconnected'
  );

  useEffect(() => {
    socket.on('connect', () => setStatus('connected'));
    socket.on('disconnect', () => setStatus('disconnected'));
    socket.on('connect_error', () => setStatus('error'));
    return () => {
      socket.off('connect');
      socket.off('disconnect');
      socket.off('connect_error');
    };
  }, []);

  return status;
}

再接続バナーの表示

ソケットが切断されたときにバナーを表示し、オフラインで再接続中であることをユーザーに知らせます。

function ConnectionBanner() {
  const status = useConnectionStatus();
  if (status === 'connected') return null;
  return (
    <div className="banner warning">
      {status === 'error' ? 'Connection failed' : 'Reconnecting...'}
    </div>
  );
}

手動での再接続

再試行を使い果たした後は、ボタンから手動で再接続できるようにします。

const [failed, setFailed] = useState(false);

socket.on('reconnect_failed', () => setFailed(true));

if (failed) {
  return (
    <button onClick={() => { setFailed(false); socket.connect(); }}>
      Retry connection
    </button>
  );
}

生の WebSocket の再接続

生の WebSocket には組み込みの再接続機能がありません。指数バックオフを手動で実装します。切断時には、新しい接続を試みる前に Math.min(delay * 2, maxDelay) の時間だけ待ちます。

function connectWithBackoff(url, attempt = 0) {
  const ws = new WebSocket(url);
  ws.onclose = () => {
    const delay = Math.min(1000 * 2 ** attempt, 30000);
    setTimeout(() => connectWithBackoff(url, attempt + 1), delay);
  };
  return ws;
}

useEffect のクリーンアップ

useEffect で追加したすべてのソケットリスナーは、クリーンアップ関数で削除する必要があります。削除しないと、メモリリークやイベント処理の重複が発生します。

useEffect(() => {
  const onData = (d) => setState(d);
  socket.on('data', onData);

  return () => {
    socket.off('data', onData); // remove specific handler reference
  };
}, []);

ハンドラーでの古いクロージャの回避

ソケットハンドラーが state や props を参照すると、古い値を保持したクロージャが作成されます。常に最新の値にアクセスするには ref を使用します。

const handlerRef = useRef(null);
handlerRef.current = (msg) => updateMessages(messages, msg); // fresh ref each render

useEffect(() => {
  const onMsg = (...args) => handlerRef.current(...args);
  socket.on('message', onMsg);
  return () => socket.off('message', onMsg);
}, []); // no deps needed

再接続時の保留メッセージの送信

切断中は送信メッセージをキューに入れ、接続が再確立したときにキューを空にして送信します。

const queue = useRef<string[]>([]);

socket.on('connect', () => {
  while (queue.current.length) {
    socket.emit('message', queue.current.shift());
  }
});

function send(text: string) {
  if (socket.connected) socket.emit('message', text);
  else queue.current.push(text);
}

再接続後のルームへの再参加

Socket.IO は切断時にルームへの参加状態を解除します。購読を復元するには、ソケットの再接続時にルームへ再参加します。

useEffect(() => {
  function rejoin() { socket.emit('join-room', roomId); }
  socket.on('connect', rejoin);
  return () => socket.off('connect', rejoin);
}, [roomId]);

グローバルエラー処理

復旧できないエラーを適切に処理します。エラー UI を表示し、最後の手段としてページの再読み込みを提示します。

socket.on('connect_error', (err) => {
  console.error('Socket error:', err.message);
  // Show user-friendly error
});

クイックチェック

useEffect のクリーンアップでソケットイベントリスナーを削除しないと、どのようなリスクがありますか?

まとめ

バックオフのオプションを使って Socket.IO の再接続を設定します。React の state に接続状態を反映し、再接続バナーを表示し、再接続後にルームへ再参加します。また、useEffect のクリーンアップでは必ずリスナーを削除してください。オフライン中は保留中のメッセージをキューに入れ、再接続時に送信します。

無料で開始

AI チューターと学ぶ React — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
88
レッスン
324

よくある質問

「再接続、エラー処理、クリーンアップ」レッスンは無料ですか?

はい。「再接続、エラー処理、クリーンアップ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「再接続、エラー処理、クリーンアップ」で何を学びますか?

切断を適切に処理し、useEffect内でsocket listenersをクリーンアップします。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「再接続、エラー処理、クリーンアップ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ブラウザで学ぶWebSocketの基礎
  2. ReactでSocket.IOを使う
  3. リアルタイムチャットコンポーネントの構築
  4. 再接続、エラー処理、クリーンアップ
← React Academyに戻る