DEV Community

Cover image for Building a Real-Time Chat Application with React Server Components
HexShift
HexShift

Posted on

4 1 1 2 2

Building a Real-Time Chat Application with React Server Components

React Server Components (RSC) offer a powerful way to improve performance by allowing server-side rendering and reducing client-side JavaScript. In this tutorial, we will build a real-time chat application that leverages React Server Components to dynamically render messages without unnecessary re-renders.


Step 1 - Setting Up the Project

First, let's create a new React project and install the necessary dependencies:

npx create-react-app real-time-chat
cd real-time-chat
npm install express react-server-dom socket.io
Enter fullscreen mode Exit fullscreen mode

We will also set up a basic Express server to handle the chat messages and establish a WebSocket connection for real-time communication.

// server.js
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const App = require('./src/App');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

let messages = [];

io.on('connection', (socket) => {
  console.log('User connected');

  socket.emit('init', messages);

  socket.on('message', (msg) => {
    messages.push(msg);
    io.emit('message', msg);  // broadcast the message to all clients
  });

  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
});

app.get('/', (req, res) => {
  const appString = ReactDOMServer.renderToString();
  res.send(`


      Real-Time Chat

        ${appString}



  `);
});

server.listen(3000, () => console.log('Server running on http://localhost:3000'));
Enter fullscreen mode Exit fullscreen mode

Step 2 - Creating the Chat Component

Next, we’ll create the Chat component to display and send messages in the chat app.

// Chat.js
import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';

const socket = io();

const Chat = () => {
  const [messages, setMessages] = useState([]);
  const [newMessage, setNewMessage] = useState('');

  useEffect(() => {
    socket.on('init', (initialMessages) => {
      setMessages(initialMessages);
    });

    socket.on('message', (message) => {
      setMessages((prevMessages) => [...prevMessages, message]);
    });

    return () => {
      socket.off('init');
      socket.off('message');
    };
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (newMessage.trim()) {
      socket.emit('message', newMessage);
      setNewMessage('');
    }
  };

  return (

      <h2>Real-Time Chat</h2>

        {messages.map((msg, index) =&gt; (
          <p>{msg}</p>
        ))}


         setNewMessage(e.target.value)}
          placeholder="Type a message"
        /&gt;
        Send


  );
};

export default Chat;
Enter fullscreen mode Exit fullscreen mode

Step 3 - Integrating the Chat Component with React Server Components

We’ll now update the App.js file to use our Chat component.

// App.js
import React from 'react';
import Chat from './Chat';

const App = () =&gt; {
  return (

      <h1>Real-Time Chat Application</h1>


  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 4 - Server-Side Rendering with React Server Components

To leverage React Server Components for rendering, we’ll modify our server.js to include React Server Components.

// server.js (updated)
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const App = require('./src/App');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

let messages = [];

io.on('connection', (socket) =&gt; {
  console.log('User connected');

  socket.emit('init', messages);

  socket.on('message', (msg) =&gt; {
    messages.push(msg);
    io.emit('message', msg);  // broadcast the message to all clients
  });

  socket.on('disconnect', () =&gt; {
    console.log('User disconnected');
  });
});

app.get('/', async (req, res) =&gt; {
  const appString = ReactDOMServer.renderToString();
  res.send(`


      Real-Time Chat

        ${appString}



  `);
});

server.listen(3000, () =&gt; console.log('Server running on http://localhost:3000'));
Enter fullscreen mode Exit fullscreen mode

Use Case Scenario

Real-time chat applications are a common feature in modern websites, from customer support to community forums. By using React Server Components, we can streamline the server-side data fetching and rendering while keeping the client-side minimal. This approach ensures that real-time updates, like new messages, are efficiently pushed to all users without unnecessary re-renders on the client.


✅ Pros and ❌ Cons

✅ Pros:

  • ⚡ Fast, server-side rendered chat experience.
  • 📡 Real-time updates using WebSocket and React Server Components.
  • 🧑‍💻 Simple integration with Express and Socket.io.

❌ Cons:

  • 🔧 More complex architecture requiring both server-side and client-side logic.
  • ⚙️ WebSocket server must be maintained for real-time communication.
  • 🧩 Handling of user sessions and message persistence can add complexity.

Summary

In this article, we built a real-time chat application using React Server Components and WebSockets with Socket.io. By leveraging server-side rendering, we created a fast and scalable application that handles dynamic updates efficiently. This technique is particularly useful for apps that require real-time communication, such as chat apps, live notifications, and collaborative platforms.

To learn more about React Server Components and how to master them for full-stack development, check out my guide:

Mastering React Server Components: A Pro Guide to Modern Full-Stack React – just $5.


If this was helpful, you can also support me here: Buy Me a Coffee

Top comments (0)