0Pricing
React Academy · Урок

Создание ленты уведомлений в реальном времени

Объедините SSE и состояние React, чтобы создать ленту уведомлений, обновляющуюся в реальном времени без участия пользователя

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

Архитектура ленты уведомлений

Лента уведомлений в реальном времени объединяет поток SSE для получения новых уведомлений с конечными точками REST для отметки элементов как прочитанных. Компонент хранит локальное состояние списка уведомлений, подписывается на поток сервера через EventSource в useEffect и обрабатывает действия пользователя (отметку как прочитанного, закрытие) с помощью оптимистичных обновлений.

Структура данных уведомления

Объект уведомления обычно имеет следующую структуру: { id: string, type: 'info' | 'warning' | 'success', message: string, timestamp: string, read: boolean }. Поле type определяет значок и цвет. Поле read показывает, подтвердил ли пользователь, что ознакомился с уведомлением. Поле timestamp позволяет группировать уведомления по периодам времени.

Подписка на поток SSE

В useEffect создайте EventSource, подключённый к /api/notifications/stream. При каждом событии сообщения разберите JSON и добавьте новое уведомление в начало состояния: setNotifications(prev => [JSON.parse(e.data), ...prev]). Добавление в начало помещает самое новое уведомление наверх, что является стандартным подходом для лент уведомлений.

Индикатор количества непрочитанных

Вычисляйте количество непрочитанных уведомлений из массива notifications без дополнительного состояния: const unreadCount = notifications.filter(n => !n.read).length. Отображайте это число в виде индикатора на значке колокольчика уведомлений. Число обновляется автоматически при каждом изменении состояния уведомлений — отдельное управление состоянием не требуется.

Отметка как прочитанного с оптимистичным обновлением

Когда пользователь нажимает на уведомление, сразу примените оптимистичное обновление прочитанного: setNotifications(prev => prev.map(n => n.id === id ? { ...n, read: true } : n)). Затем в фоновом режиме отправьте запрос PATCH к /api/notifications/:id с { read: true }. Если запрос завершится ошибкой, отмените оптимистичное обновление.

Группировка уведомлений по времени

Сгруппируйте уведомления для отображения: «Сегодня» (тот же календарный день), «Вчера» и «Более ранние». Определяйте группу по метке времени уведомления и текущей дате: const today = new Date().toDateString(). Отображайте каждую группу как отдельный раздел с заголовком. Это значительно упрощает просмотр длинного списка уведомлений.

Всплывающие уведомления для фоновой активности

Если пользователь находится на другой странице и через SSE поступает новое уведомление, покажите всплывающее уведомление вместо обновления списка уведомлений или в дополнение к нему. Используйте глобальный контекст уведомлений или хранилище Zustand, доступное и подписчику SSE, и компоненту отображения всплывающих уведомлений. Всплывающее уведомление исчезает через несколько секунд, а само уведомление сохраняется в списке.

Глобальный контекст уведомлений

Если уведомления должны отображаться во всём приложении, храните их в контексте React или хранилище Zustand на корневом уровне приложения. Подписка SSE размещается в компоненте-поставщике рядом с верхним уровнем дерева компонентов. Любой компонент может читать уведомления или отправлять новые через общее хранилище, что позволяет отображать всплывающие уведомления на любой странице.

Переподключение SSE при возвращении к вкладке

EventSource автоматически обрабатывает переподключение при разрыве сети, но изменения видимости вкладки — это другая ситуация. Когда пользователь возвращается к вкладке после долгого отсутствия, соединение SSE могло быть закрыто сервером. EventSource подключается снова автоматически, а механизм Last-Event-ID повторно отправляет все уведомления, которые пользователь пропустил, пока вкладка была в фоновом режиме.

Сохранение уведомлений при переходах

Одностраничные приложения теряют хранящееся в памяти состояние уведомлений при переходе со страницы. Сохраняйте уведомления в localStorage после каждого обновления: localStorage.setItem('notifications', JSON.stringify(notifications)). При монтировании инициализируйте состояние из localStorage до подключения потока SSE. Это сохраняет историю уведомлений при переходах между страницами.

Шаблон конечной точки SSE

Серверная конечная точка SSE должна устанавливать определённые заголовки: Content-Type: text/event-stream, Cache-Control: no-cache и Connection: keep-alive. В Express/NestJS отправляйте события в виде data: ${JSON.stringify(payload)}\n\n — обратите внимание на двойной перевод строки, который обозначает конец события. Сервер должен отправлять данные после каждой записи, чтобы браузер сразу получал событие.

Шаблон конечной точки потока SSE

Какое значение заголовка Content-Type является правильным для конечной точки SSE (событий, отправляемых сервером)?

Итоги урока: лента уведомлений в реальном времени

Ленты уведомлений объединяют подписку SSE (useEffect с очисткой EventSource) с изменениями через REST (PATCH для отметки как прочитанного). Форма данных включает идентификатор, тип, сообщение, метку времени и признак прочитанности. Вычисляйте unreadCount фильтрацией, а для отображения группируйте уведомления по категориям «сегодня», «вчера» и «более ранние». Используйте глобальный контекст или Zustand для всплывающих уведомлений на разных страницах. Сохраняйте данные в localStorage, чтобы они не терялись при переходах. Для конечной точки SSE требуются Content-Type: text/event-stream, Cache-Control: no-cache и разделители событий в виде двойного перевода строки.

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

Урок «Создание ленты уведомлений в реальном времени» бесплатный?

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

Чему я научусь в уроке «Создание ленты уведомлений в реальном времени»?

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

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

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

Сколько времени занимает урок «Создание ленты уведомлений в реальном времени»?

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

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

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

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

  1. Сравнение SSE, WebSockets и опроса
  2. Использование потоков SSE в React с EventSource
  3. Шаблон длительного опроса и логика переподключения
  4. Создание ленты уведомлений в реальном времени
← Назад к React Academy