React Academy · Les

Een realtime chatcomponent bouwen

Toon liveberichten in een scrollende chatlijst met WebSocket-events en React-state.

Les 3 van 414 stappen

Een realtime chatcomponent bouwen is een gratis React Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject React Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus React Academy bevat in totaal 4 lessen.

Architectuur van een chatcomponent

Een realtimechat bestaat uit drie delen: een berichtenlijst (weergave), een berichtinvoer (verzenden) en een verbindingslaag voor WebSocket/Socket.IO. Houd de socketlogica in een aangepaste hook.

Gegevensstructuur van berichten

Definieer een TypeScript-interface voor chatberichten, zodat de component overal typeveilig blijft.

interface Message {
  id: string;
  text: string;
  sender: string;
  timestamp: number;
}

const [messages, setMessages] = useState<Message[]>([]);

useChat-hook

Verpak de verbinding, de berichtstatus en de verzendfunctie in éé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 };
}

Berichtenlijstcomponent

Geef berichten weer in een lijst waarin je kunt scrollen. Gebruik useRef op het sentinel-element onderaan en scroll ernaartoe wanneer er nieuwe berichten binnenkomen.

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>
  );
}

Berichtinvoercomponent

Een gecontroleerde invoer die een bericht uitstuurt wanneer je op Enter drukt of op een knop klikt. Wis de invoer nadat het bericht is verzonden.

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>
  );
}

De chatinterface samenstellen

Combineer de hook en subcomponenten in een ChatRoom-component.

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>
  );
}

Optimistische updates

Voeg het bericht onmiddellijk aan de lokale status toe voordat de server het bevestigt, zodat de gebruiker direct feedback krijgt. Stem de status opnieuw af of verwijder het bericht als de server een fout retourneert.

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));
  });
}, []);

Typindicatoren

Stuur bij elke wijziging in de invoer (met vertraging) een typing-gebeurtenis uit en luister naar typgebeurtenissen van anderen om een indicator weer te geven.

const emitTyping = useMemo(() => debounce(() => socket.emit('typing'), 300), []);

useEffect(() => {
  socket.on('user-typing', (user) => setTypingUser(user));
  return () => socket.off('user-typing');
}, []);

Tijdstempels van berichten

Formatteer tijdstempels met Intl.DateTimeFormat voor een weergave die rekening houdt met de landinstelling.

function formatTime(ts: number) {
  return new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit' }).format(ts);
}

<span className="timestamp">{formatTime(msg.timestamp)}</span>

Leesbevestigingen

Stuur een read-gebeurtenis uit wanneer de gebruiker berichten bekijkt en luister naar leesbevestigingen van de server om vinkjes weer te geven.

Gevirtualiseerde berichtenlijst

Gebruik voor lange chatgeschiedenissen react-window of react-virtual om de berichtenlijst te virtualiseren en alleen zichtbare rijen weer te geven.

Berichtgeschiedenis beperken

Beperk de berichtenarray in de status om onbeperkte geheugengroei tijdens lange sessies te voorkomen.

socket.on('message', (msg: Message) => {
  setMessages(prev => [...prev.slice(-499), msg]); // keep last 500
});

Korte controle

Wat is het doel van naar de sentinel-div onderaan scrollen wanneer er nieuwe berichten binnenkomen in een chatlijst?

Samenvatting

Bouw een realtimechat met een useChat-hook waarin de socketlogica is ondergebracht, een MessageList met automatisch scrollen en een MessageInput die na het verzenden wordt gewist. Gebruik optimistische updates voor directe feedback en beperk de berichtgeschiedenis om geheugenlekken te voorkomen.

Gratis beginnen

Leer React met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
88
Lessen
324

Veelgestelde vragen

Is de les “Een realtime chatcomponent bouwen” gratis?

Ja — de volledige tekst van “Een realtime chatcomponent bouwen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus React Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus React Academy bevat in totaal 4 lessen.

Wat leer ik in “Een realtime chatcomponent bouwen”?

Toon liveberichten in een scrollende chatlijst met WebSocket-events en React-state. Je oefent met React Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met React Academy te beginnen?

Ervaring vooraf is niet nodig. React Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Een realtime chatcomponent bouwen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over React Academy?

Ja. Elke les over React Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. WebSocket-beginselen in de browser
  2. Socket.IO gebruiken met React
  3. Een realtime chatcomponent bouwen
  4. Opnieuw verbinden, foutafhandeling en opruimen
← Terug naar React Academy