Bygge en chatkomponent i sanntid
Vis meldinger i sanntid i en scrollbar chatliste ved hjelp av WebSocket-events og React-state.
Bygge en chatkomponent i sanntid er en gratis leksjon i React Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i React Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i React Academy inneholder totalt 4 leksjoner.
Arkitektur for chat-komponenten
En sanntidschat har tre deler: en meldingsliste (visning), et meldingsfelt (sending) og et WebSocket-/Socket.IO-tilkoblingslag. Hold socket-logikken i en egen hook.
Meldingsdatastruktur
Definer et TypeScript-grensesnitt for chatmeldinger, slik at komponenten beholder typesikkerheten gjennomgående.
interface Message {
id: string;
text: string;
sender: string;
timestamp: number;
}
const [messages, setMessages] = useState<Message[]>([]);useChat-hook
Samle tilkoblingen, meldingstilstanden og sendefunksjonen i én hook.
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 };
}Meldingslistekomponent
Rendrer meldinger i en liste med rulling. Bruk useRef på sentinel-elementet nederst, og rull dit når nye meldinger kommer inn.
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 for meldingsfelt
Et kontrollert inndatafelt som sender ved Enter eller knappetrykk. Tøm feltet etter sending.
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>
);
}Sette sammen chatgrensesnittet
Sett sammen hooken og underkomponentene til en ChatRoom-komponent.
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>
);
}Optimistiske oppdateringer
Legg meldingen til i lokal state umiddelbart, før serveren bekrefter den, slik at brukeren får umiddelbar tilbakemelding. Synkroniser eller fjern meldingen hvis serveren returnerer en feil.
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));
});
}, []);Skriveindikatorer
Send ut en typing-hendelse ved endringer i inndata (med debounce), og lytt etter andres skrivehendelser for å vise en indikator.
const emitTyping = useMemo(() => debounce(() => socket.emit('typing'), 300), []);
useEffect(() => {
socket.on('user-typing', (user) => setTypingUser(user));
return () => socket.off('user-typing');
}, []);Tidsstempler for meldinger
Formater tidsstempler med Intl.DateTimeFormat for lokalitetstilpasset visning.
function formatTime(ts: number) {
return new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit' }).format(ts);
}
<span className="timestamp">{formatTime(msg.timestamp)}</span>Lesebekreftelser
Send ut en read-hendelse når brukeren ser på meldinger, og lytt etter lesebekreftelser fra serveren for å vise avkrysningsmerker.
Virtualisert meldingsliste
For lange chathistorikker kan du bruke react-window eller react-virtual til å virtualisere meldingslisten og bare rendre synlige rader.
Begrense meldingshistorikken
Begrens meldingsarrayet i state for å hindre ubegrenset minnevekst i lange økter.
socket.on('message', (msg: Message) => {
setMessages(prev => [...prev.slice(-499), msg]); // keep last 500
});Kort sjekk
Hva er hensikten med å rulle til sentinel-div-elementet nederst når nye meldinger kommer inn i en chatliste?
Oppsummering
Bygg en sanntidschat med en useChat-hook som samler socket-logikken, en MessageList med automatisk rulling og en MessageInput som tømmes ved sending. Bruk optimistiske oppdateringer for umiddelbar tilbakemelding, og begrens meldingshistorikken for å unngå minnelekkasjer.
Lær deg React med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 88
- Leksjoner
- 324
Ofte stilte spørsmål
Er leksjonen «Bygge en chatkomponent i sanntid» gratis?
Ja – hele teksten i «Bygge en chatkomponent i sanntid» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av React Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i React Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Bygge en chatkomponent i sanntid»?
Vis meldinger i sanntid i en scrollbar chatliste ved hjelp av WebSocket-events og React-state. Du øver på React Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med React Academy?
Ingen tidligere erfaring er nødvendig. React Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Bygge en chatkomponent i sanntid»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne React Academy-leksjonen?
Ja. Alle React Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Grunnleggende om WebSocket i nettleseren
- Bruke Socket.IO med React
- Bygge en chatkomponent i sanntid
- Gjenoppretting av tilkobling, feilhåndtering og opprydding