React Academy · Урок

Переподключение, обработка ошибок и очистка

Корректно обрабатывайте разрывы соединения и удаляйте обработчики сокета в useEffect.

Урок 4 из 413 шагов

«Переподключение, обработка ошибок и очистка» — бесплатный урок React Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Почему важно переподключение

Перебои в сети часто происходят на мобильных устройствах. Без логики переподключения пользователи незаметно теряют соединение в реальном времени. Хорошая стратегия автоматически повторяет попытки с увеличением интервала.

Автоматическое переподключение Socket.IO

Socket.IO по умолчанию переподключается автоматически. Настройте reconnectionAttempts, reconnectionDelay и reconnectionDelayMax в параметрах io().

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
  };
}, []);

Предотвращение устаревших замыканий в обработчиках

Когда обработчик сокета обращается к состоянию или свойствам, он захватывает устаревшее замыкание. Используйте ссылку, чтобы всегда получать последнее значение.

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]);

Глобальная обработка ошибок

Корректно обрабатывайте неустранимые ошибки: показывайте интерфейс ошибки и предлагайте перезагрузить страницу как последнее средство.

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

Быстрая проверка

Каков риск того, что обработчик событий сокета не будет удалён в функции очистки useEffect?

Итоги

Настройте переподключение Socket.IO с параметрами увеличения интервала. Отражайте состояние соединения в состоянии React, показывайте баннер переподключения, повторно подключайтесь к комнатам после восстановления соединения и всегда удаляйте обработчики в функции очистки useEffect. Ставьте ожидающие сообщения в очередь, пока пользователь не в сети, и отправляйте их после переподключения.

Можно начать бесплатно

Изучай React с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
88
Уроки
324

Часто задаваемые вопросы

Урок «Переподключение, обработка ошибок и очистка» бесплатный?

Да — полный текст урока «Переподключение, обработка ошибок и очистка» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Переподключение, обработка ошибок и очистка»?

Корректно обрабатывайте разрывы соединения и удаляйте обработчики сокета в useEffect. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Переподключение, обработка ошибок и очистка»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы WebSocket в браузере
  2. Использование Socket.IO с React
  3. Создание компонента чата в реальном времени
  4. Переподключение, обработка ошибок и очистка
← Назад к React Academy