Budowanie komponentu czatu w czasie rzeczywistym
Wyświetlanie wiadomości na żywo na przewijanej liście czatu za pomocą zdarzeń WebSocket i stanu React.
Budowanie komponentu czatu w czasie rzeczywistym to bezpłatna lekcja React Academy na CoddyKit. To lekcja 3 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 komponentu czatu
Czat działający w czasie rzeczywistym składa się z trzech części: listy wiadomości (wyświetlanie), pola wprowadzania wiadomości (wysyłanie) oraz warstwy połączenia WebSocket/Socket.IO. Logikę gniazda należy umieścić w niestandardowym hooku.
Kształt danych wiadomości
Zdefiniuj interfejs TypeScript dla wiadomości czatu, aby zachować bezpieczeństwo typów w całym komponencie.
interface Message {
id: string;
text: string;
sender: string;
timestamp: number;
}
const [messages, setMessages] = useState<Message[]>([]);Hook useChat
Umieść obsługę połączenia, stan wiadomości i funkcję wysyłania w jednym hooku.
function useChat(roomId: string) {
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
socket.connect();
socket.emit('join-room', roomId);
socket.on('message', (msg: Message) => setMessages(m => [...m, msg]));
return () => {
socket.off('message');
socket.emit('leave-room', roomId);
socket.disconnect();
};
}, [roomId]);
const sendMessage = useCallback((text: string) => {
const msg: Message = { id: crypto.randomUUID(), text, sender: 'me', timestamp: Date.now() };
socket.emit('message', msg);
}, []);
return { messages, sendMessage };
}Komponent listy wiadomości
Renderuj wiadomości na przewijanej liście. Użyj useRef dla znacznika na dole listy i przewijaj do niego po nadejściu nowych wiadomości.
function MessageList({ messages }: { messages: Message[] }) {
const bottomRef = useRef<HTMLDivElement>(null);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
return (
<div className="message-list">
{messages.map(msg => (
<div key={msg.id} className={`msg ${msg.sender === 'me' ? 'mine' : 'theirs'}`}>
<span>{msg.sender}</span>
<p>{msg.text}</p>
</div>
))}
<div ref={bottomRef} />
</div>
);
}Komponent pola wiadomości
Jest to kontrolowane pole, które emituje wiadomość po naciśnięciu Enter lub kliknięciu przycisku. Wyczyść pole po wysłaniu.
function MessageInput({ onSend }: { onSend: (text: string) => void }) {
const [text, setText] = useState('');
const handleSend = () => {
if (!text.trim()) return;
onSend(text.trim());
setText('');
};
return (
<div className="input-row">
<input
value={text}
onChange={e => setText(e.target.value)}
onKeyDown={e => e.key === 'Enter' && handleSend()}
placeholder="Type a message..."
/>
<button onClick={handleSend}>Send</button>
</div>
);
}Składanie interfejsu czatu
Połącz hook i podkomponenty w komponent ChatRoom.
function ChatRoom({ roomId }: { roomId: string }) {
const { messages, sendMessage } = useChat(roomId);
return (
<div className="chat-room">
<h2>Room: {roomId}</h2>
<MessageList messages={messages} />
<MessageInput onSend={sendMessage} />
</div>
);
}Optymistyczne aktualizacje
Dodaj wiadomość do stanu lokalnego natychmiast, zanim serwer ją potwierdzi, aby zapewnić natychmiastową informację zwrotną. Jeśli serwer zwróci błąd, uzgodnij stan ponownie lub usuń wiadomość.
const sendMessage = useCallback((text: string) => {
const optimistic: Message = { id: crypto.randomUUID(), text, sender: 'me', timestamp: Date.now() };
setMessages(m => [...m, optimistic]); // instant feedback
socket.emit('message', optimistic, (err) => {
if (err) setMessages(m => m.filter(msg => msg.id !== optimistic.id));
});
}, []);Wskaźniki pisania
Emituj zdarzenie typing przy zmianie zawartości pola (z opóźnieniem dzięki debounce) i nasłuchuj zdarzeń pisania innych osób, aby wyświetlać wskaźnik.
const emitTyping = useMemo(() => debounce(() => socket.emit('typing'), 300), []);
useEffect(() => {
socket.on('user-typing', (user) => setTypingUser(user));
return () => socket.off('user-typing');
}, []);Znaczniki czasu wiadomości
Formatuj znaczniki czasu za pomocą Intl.DateTimeFormat, aby wyświetlać je zgodnie z ustawieniami lokalnymi.
function formatTime(ts: number) {
return new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit' }).format(ts);
}
<span className="timestamp">{formatTime(msg.timestamp)}</span>Potwierdzenia odczytu
Emituj zdarzenie read, gdy użytkownik wyświetla wiadomości, i nasłuchuj potwierdzeń odczytu z serwera, aby wyświetlać znaczniki wyboru.
Wirtualizowana lista wiadomości
W przypadku długiej historii czatu użyj react-window lub react-virtual, aby zwirtualizować listę wiadomości i renderować tylko widoczne wiersze.
Ograniczanie historii wiadomości
Ogranicz tablicę wiadomości w stanie, aby zapobiec nieograniczonemu wzrostowi zużycia pamięci podczas długich sesji.
socket.on('message', (msg: Message) => {
setMessages(prev => [...prev.slice(-499), msg]); // keep last 500
});Szybkie sprawdzenie
Jaki jest cel przewijania do elementu div będącego znacznikiem na dole listy, gdy w czacie pojawiają się nowe wiadomości?
Podsumowanie
Zbuduj czat działający w czasie rzeczywistym za pomocą hooka useChat zawierającego logikę gniazda, komponentu MessageList z automatycznym przewijaniem oraz komponentu MessageInput, który czyści pole po wysłaniu. Używaj optymistycznych aktualizacji, aby zapewnić natychmiastową informację zwrotną, i ograniczaj historię wiadomości, aby uniknąć wycieków pamięci.
Ucz się React dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 88
- Lekcje
- 324
Często zadawane pytania
Czy lekcja „Budowanie komponentu czatu w czasie rzeczywistym” jest bezpłatna?
Tak — pełny tekst „Budowanie komponentu czatu 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 komponentu czatu w czasie rzeczywistym”?
Wyświetlanie wiadomości na żywo na przewijanej liście czatu za pomocą zdarzeń WebSocket i stanu React. Ć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 3 z 4.
Ile czasu zajmuje lekcja „Budowanie komponentu czatu 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
- Podstawy WebSocket w przeglądarce
- Używanie Socket.IO z React
- Budowanie komponentu czatu w czasie rzeczywistym
- Ponowne łączenie, obsługa błędów i czyszczenie