0Pricing
React Academy · Lekcja

Budowanie kanału powiadomień w czasie rzeczywistym

Połączą Państwo SSE ze stanem Reacta, aby zbudować kanał powiadomień aktualizowany w czasie rzeczywistym bez interakcji użytkownika.

Budowanie kanału powiadomień w czasie rzeczywistym to bezpłatna lekcja React Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.

Architektura kanału powiadomień

Kanał powiadomień w czasie rzeczywistym łączy strumień SSE z przychodzącymi powiadomieniami i endpointy REST służące do oznaczania elementów jako przeczytane. Komponent przechowuje lokalnie stan listy powiadomień, subskrybuje strumień serwera za pomocą EventSource w useEffect i obsługuje interakcje użytkownika (oznaczanie jako przeczytane, odrzucanie) za pomocą optymistycznych aktualizacji.

Struktura danych powiadomienia

Obiekt powiadomienia zwykle ma następującą strukturę: { id: string, type: 'info' | 'warning' | 'success', message: string, timestamp: string, read: boolean }. Pole type określa ikonę i kolor. Pole read informuje, czy użytkownik potwierdził zapoznanie się z powiadomieniem. Pole timestamp umożliwia grupowanie według przedziałów czasowych.

Subskrybowanie strumienia SSE

W useEffect należy utworzyć EventSource połączony z /api/notifications/stream. Przy każdym zdarzeniu message należy przetworzyć kod JSON i dodać nowe powiadomienie na początku stanu: setNotifications(prev => [JSON.parse(e.data), ...prev]). Dodawanie na początku (zachowanie unshift) umieszcza najnowsze powiadomienie na górze, co jest standardem w kanałach powiadomień.

Plakietka z liczbą nieprzeczytanych

Liczbę nieprzeczytanych należy wyliczać z tablicy powiadomień bez dodatkowego stanu: const unreadCount = notifications.filter(n => !n.read).length. Należy wyświetlić ją jako plakietkę przy ikonie dzwonka powiadomień. Liczba aktualizuje się automatycznie za każdym razem, gdy zmienia się stan powiadomień — nie jest potrzebne oddzielne zarządzanie stanem.

Oznaczanie jako przeczytane z optymistyczną aktualizacją

Po kliknięciu powiadomienia przez użytkownika należy natychmiast zastosować optymistyczną aktualizację odczytania: setNotifications(prev => prev.map(n => n.id === id ? { ...n, read: true } : n)). Następnie w tle należy wysłać żądanie PATCH do /api/notifications/:id z wartością { read: true }. Jeśli żądanie się nie powiedzie, należy wycofać optymistyczną aktualizację.

Grupowanie powiadomień według czasu

Powiadomienia można grupować na potrzeby wyświetlania: „Dzisiaj” (ten sam dzień kalendarzowy), „Wczoraj” i „Starsze”. Grupę należy obliczyć na podstawie znacznika czasu powiadomienia i bieżącej daty: const today = new Date().toDateString(). Każdą grupę należy renderować jako oddzielną sekcję z etykietą nagłówka. Znacznie ułatwia to przeglądanie długiej listy powiadomień.

Powiadomienia toast o aktywności w tle

Gdy użytkownik znajduje się na innej stronie i przez SSE nadejdzie nowe powiadomienie, należy wyświetlić toast zamiast aktualizowania listy powiadomień lub dodatkowo obok tej aktualizacji. Należy użyć globalnego kontekstu powiadomień albo magazynu Zustand, do którego mogą mieć dostęp zarówno subskrybent SSE, jak i renderer toastów. Toast znika po kilku sekundach, a powiadomienie pozostaje na liście.

Globalny kontekst powiadomień

Powiadomienia wyświetlane w całej aplikacji należy przechowywać w kontekście React lub magazynie Zustand na poziomie głównym aplikacji. Subskrypcja SSE powinna znajdować się w komponencie providera blisko szczytu drzewa. Każdy komponent może odczytywać powiadomienia lub wysyłać nowe za pośrednictwem współdzielonego magazynu, co umożliwia renderowanie toastów na dowolnej stronie.

Ponowne łączenie SSE po uaktywnieniu karty

EventSource automatycznie obsługuje ponowne łączenie po utracie sieci, ale zmiany widoczności karty to inny przypadek. Gdy użytkownik wróci do karty po dłuższej nieobecności, serwer mógł zakończyć połączenie SSE. EventSource ponownie połączy się automatycznie, a mechanizm Last-Event-ID odtworzy wszystkie powiadomienia, które użytkownik przegapił, gdy karta działała w tle.

Zachowywanie powiadomień podczas nawigacji

Aplikacje jednostronicowe tracą przechowywany w pamięci stan powiadomień po przejściu na inną stronę. Po każdej aktualizacji należy zapisywać powiadomienia w localStorage: localStorage.setItem('notifications', JSON.stringify(notifications)). Przy montowaniu komponentu należy zainicjalizować stan na podstawie localStorage, zanim połączy się strumień SSE. Zachowuje to historię powiadomień podczas nawigacji między stronami.

Schemat endpointu SSE

Endpoint SSE po stronie serwera musi ustawić określone nagłówki: Content-Type: text/event-stream, Cache-Control: no-cache oraz Connection: keep-alive. W Express/NestJS zdarzenia należy zapisywać jako data: ${JSON.stringify(payload)}\n\n — należy zwrócić uwagę na podwójny znak nowej linii, który sygnalizuje koniec zdarzenia. Po każdym zapisie serwer musi opróżnić bufor, aby przeglądarka natychmiast otrzymała zdarzenie.

Schemat endpointu strumienia SSE

Jaki jest poprawny nagłówek Content-Type dla endpointu SSE (Server-Sent Events)?

Podsumowanie lekcji: kanał powiadomień w czasie rzeczywistym

Kanały powiadomień łączą subskrypcję SSE (useEffect z czyszczeniem EventSource) z mutacjami REST (PATCH do oznaczania jako przeczytane). Kształt danych: {id, type, message, timestamp, read}. Liczbę unreadCount należy wyliczać za pomocą filter, a powiadomienia grupować na potrzeby wyświetlania według kategorii dzisiaj/wczoraj/starsze. Do toastów dostępnych na różnych stronach należy użyć globalnego kontekstu lub Zustand. Aby zachować dane podczas nawigacji, należy zapisywać je w localStorage. Endpoint SSE wymaga nagłówków Content-Type: text/event-stream, Cache-Control: no-cache oraz separatorów zdarzeń w postaci podwójnego znaku nowej linii.

Często zadawane pytania

Czy lekcja „Budowanie kanału powiadomień w czasie rzeczywistym” jest bezpłatna?

Tak — pełny tekst „Budowanie kanału powiadomień w czasie rzeczywistym” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Budowanie kanału powiadomień w czasie rzeczywistym”?

Połączą Państwo SSE ze stanem Reacta, aby zbudować kanał powiadomień aktualizowany w czasie rzeczywistym bez interakcji użytkownika. Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć React Academy?

Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Budowanie kanału powiadomień w czasie rzeczywistym”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?

Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Porównanie SSE, WebSockets i pollingu
  2. Korzystanie ze strumieni SSE w React z EventSource
  3. Wzorzec long pollingu i logika ponownego łączenia
  4. Budowanie kanału powiadomień w czasie rzeczywistym
← Powrót do React Academy