Hone logo
Hone
Problems

Real-Time Chat Application: Implementing Live Updates with WebSockets

This challenge focuses on building a fundamental aspect of modern web applications: real-time updates. You will implement a simple chat application where messages sent by one user are instantly visible to all other connected users without requiring a page refresh. This skill is crucial for creating dynamic user experiences in applications like live dashboards, collaborative tools, and, of course, chat platforms.

Problem Description

Your task is to develop a React component that simulates a real-time chat feature. This component should:

  1. Display Messages: Render a list of chat messages. Each message should show the sender's name and the message content.
  2. Send Messages: Allow a user to type a message and send it.
  3. Receive Real-Time Updates: When a new message is sent by any connected user (simulated in this challenge), it should be immediately appended to the message list for all connected users.

You will simulate the real-time aspect by using a simplified mechanism that mimics WebSocket behavior. For this challenge, we'll use a setInterval to periodically "broadcast" new messages to all connected "clients" (i.e., instances of your React component).

Key Requirements

  • Create a functional React component (e.g., ChatWindow).
  • Manage the list of messages in the component's state.
  • Implement an input field and a send button for users to submit messages.
  • Simulate receiving new messages using setInterval and a simple broadcasting function.
  • Ensure that when a new message is received, the UI updates to display it.
  • Use TypeScript for type safety.

Expected Behavior

When the ChatWindow component is rendered, it should display an empty message list and an input area. As new messages are "received" (simulated by the setInterval), they should appear in the message list. If the user "sends" a message, it should also be added to the list.

Edge Cases to Consider

  • Initial State: The application should gracefully handle displaying messages when there are none.
  • Empty Messages: Prevent sending empty messages.

Examples

Example 1: Initial Load and Receiving First Message

Input:
- ChatWindow component is rendered.
- A simulated "broadcast" function is called after 2 seconds, sending: { id: 'msg-1', sender: 'Alice', content: 'Hello everyone!' }

Output:
The component renders an input field and a send button. Initially, the message list is empty.
After 2 seconds, the message list updates to:
[
  { id: 'msg-1', sender: 'Alice', content: 'Hello everyone!' }
]

Example 2: Sending a Message and Receiving Another

Input:
- User types "How are you?" and clicks send.
- The component internally adds: { id: 'msg-2', sender: 'Bob', content: 'How are you?' }
- After another 3 seconds, a simulated "broadcast" sends: { id: 'msg-3', sender: 'Charlie', content: 'I'm good!' }

Output:
The message list updates to:
[
  { id: 'msg-2', sender: 'Bob', content: 'How are you?' },
  { id: 'msg-3', sender: 'Charlie', content: 'I'm good!' }
]

Example 3: Sending an Empty Message

Input:
- User leaves the input field empty and clicks send.

Output:
The message list remains unchanged. No new message is added.

Constraints

  • Message ID Uniqueness: Assume that message IDs generated by the simulated broadcast will be unique.
  • Sender Names: Sender names will be strings.
  • Message Content: Message content will be strings.
  • Simulation Interval: The simulated broadcast should occur at intervals of 2-5 seconds.
  • Number of Simulated Broadcasts: Simulate at least 5 broadcasted messages throughout the component's lifecycle.

Notes

  • You'll need to define TypeScript interfaces for your message objects.
  • For the simulation, you can use a global setInterval or manage it within a useEffect hook.
  • The "broadcasting" mechanism can be a simple function that calls a callback provided to your ChatWindow component, or you can directly manipulate a shared state if you are running multiple instances of the component in your local development environment. For this challenge, let's assume a simulateIncomingMessage function will be provided that you can call.
  • Focus on the React component logic and state management for handling real-time updates. You do not need to implement a full backend or actual WebSocket server.
  • Consider how to handle component unmounting to prevent memory leaks (e.g., clearing intervals).
Loading editor...
typescript