Building a Real-Time Chat Application with React and Socket.IO
Introduction
This article guides you through creating a basic real-time chat application. We'll leverage React for the user interface and Socket.IO for handling real-time bidirectional communication between the client and server.
Prerequisites
- Node.js and npm installed
- Basic understanding of React
Setting up the Server (Node.js with Socket.IO)
First, create a server-side application using Node.js and install the necessary dependencies:
mkdir chat-server
cd chat-server
npm init -y
npm install socket.io express
Create a file named server.js
and add the following code:
const express = require('express');
const http = require('http');
const { Server } = require("socket.io");
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000", // Replace with your React app's URL
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
socket.on('chat message', (msg) => {
io.emit('chat message', { message: msg, id: socket.id });
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
const port = 4000; // Example port
server.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
Run the server:
node server.js
Building the React Client
Create a new React application:
npx create-react-app chat-client
cd chat-client
npm install socket.io-client
Replace the contents of src/App.js
with the following:
import React, { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';
import './App.css';
const socket = io('http://localhost:4000'); // Replace with your server URL
function App() {
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState('');
const messagesEndRef = useRef(null);
useEffect(() => {
socket.on('chat message', (msg) => {
setMessages(prevMessages => [...prevMessages, msg]);
});
return () => {
socket.off('chat message');
};
}, []);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}, [messages]);
const sendMessage = (e) => {
e.preventDefault();
if (newMessage) {
socket.emit('chat message', newMessage);
setNewMessage('');
}
};
return (
<div className="App">
<h1>Real-time Chat</h1>
<div className="messages">
{messages.map((msg, index) => (
<div key={index}>
<strong>User {msg.id}:</strong> {msg.message}
</div>
))}
<div ref={messagesEndRef} />
</div>
<form onSubmit={sendMessage}>
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
placeholder="Type your message..."
/>
<button type="submit">Send</button>
</form>
</div>
);
}
export default App;
Add some basic styling to src/App.css
:
.App {
text-align: center;
}
.messages {
height: 300px;
overflow-y: scroll;
border: 1px solid #ccc;
margin-bottom: 10px;
padding: 10px;
}
Start the React application:
npm start
Conclusion
You have now built a simple real-time chat application using React and Socket.IO. This example can be expanded upon to include features such as user authentication, private messaging, and more complex UI elements.