Как настроить WebSockets в React приложении?react-100

Подготовка

Перед началом работы убедитесь, что:

  1. У вас есть WebSocket сервер (например, Node.js с ws или Socket.IO)
  2. React приложение создано (CRA, Vite или другой сборщик)

Базовый подход

Используем нативный WebSocket API:

import { useState, useEffect } from 'react';

const WebSocketComponent = () => {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    // 1. Инициализация соединения
    const ws = new WebSocket('wss://your-websocket-server.com');

    // 2. Настройка обработчиков событий
    ws.onopen = () => {
      console.log('WebSocket connected');
      setSocket(ws);
    };

    ws.onmessage = (event) => {
      // 3. Обработка входящих сообщений
      setMessages(prev => [...prev, event.data]);
    };

    ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };

    ws.onclose = () => {
      console.log('WebSocket disconnected');
    };

    // 4. Очистка при размонтировании
    return () => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.close();
      }
    };
  }, []);

  const sendMessage = () => {
    if (socket && socket.readyState === WebSocket.OPEN) {
      socket.send(input);
      setInput('');
    }
  };

  return (
    <div>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
      />
      <button onClick={sendMessage}>Send</button>
      <div>
        {messages.map((msg, index) => (
          <p key={index}>{msg}</p>
        ))}
      </div>
    </div>
  );
};

Продвинутая настройка

1. Автоматический реконнект

useEffect(() => {
  let ws;
  let reconnectInterval;

  const connect = () => {
    ws = new WebSocket('wss://your-server.com');

    ws.onclose = (e) => {
      console.log(`Socket closed. Reconnecting...`, e.reason);
      reconnectInterval = setTimeout(connect, 5000);
    };

    // ...другие обработчики
  };

  connect();

  return () => {
    clearTimeout(reconnectInterval);
    ws?.close();
  };
}, []);

2. Использование контекста

Для доступа к WebSocket во всем приложении:

const WebSocketContext = createContext(null);

export const WebSocketProvider = ({ children }) => {
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    const ws = new WebSocket('wss://your-server.com');
    setSocket(ws);
    return () => ws.close();
  }, []);

  return (
    <WebSocketContext.Provider value={socket}>
      {children}
    </WebSocketContext.Provider>
  );
};

Библиотеки для WebSockets

  1. Socket.IO Client:
npm install socket.io-client
import { io } from 'socket.io-client';
const socket = io('https://your-server.com');
  1. react-use-websocket:
npm install react-use-websocket
import useWebSocket from 'react-use-websocket';
const { sendMessage } = useWebSocket('wss://your-server.com');

Обработка ошибок

Важные проверки:

  1. Состояние соединения:
if (socket.readyState !== WebSocket.OPEN) {
  // Обработка случая, когда соединение не готово
}
  1. Таймауты соединения
  2. Ограничение частоты сообщений

Производительность

  1. Используйте useMemo для оптимизации:
const messageList = useMemo(() => (
  messages.map(msg => <Message key={msg.id} data={msg} />)
), [messages]);
  1. Дебаунс для частых обновлений

Резюмируем

  1. Используйте useEffect для управления жизненным циклом WebSocket
  2. Всегда закрывайте соединение при размонтировании
  3. Для production-решений рассмотрите Socket.IO или специализированные хуки
  4. Реализуйте обработку ошибок и реконнект
  5. Оптимизируйте рендеринг при частых обновлениях