Things that we will be touching on this session
- React.js front end
- React Material Design
- Node.js & Express.js REST API
First we create our front end app
$ create-react-app chatit
cd into the directory by cd chatit
and run npm start
now you are up and running with react. In your http://localhost:3000/
and you should see the application up and running.
Let's create a new component ChatRoom
component and place it to our App
component.
import React, { Component } from 'react'
import ChatRoom from './components/ChatRoom'
class App extends Component {
render() {
return (
<div className="App">
<ChatRoom />
</div>
);
}
}
export default App
import React from 'react'
class ChatRoom extends React.Component {
render() {
return(
<h1>This is Room</h1>
)
}
}
export default ChatRoom
Now we see something like this in our browser Cool. Lets add some html now in our jsx to make it look like a chatroom.
class ChatRoom extends React.Component {
render() {
return(
<div>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</div>
)
}
}
Now we are ready to set up socket.io in our client side.
in the root of our application we do run the following comand to get the socket.io installed in client side.
npm install socket.io-client --save
now we are going to add socket client in our ChatRoom component.
Like so we do the following
import React from 'react'
import SocketIOClient from 'socket.io-client'
class ChatRoom extends React.Component {
constructor(props){
super(props)
this.state = {
value: '',
msg: []
}
this.socket = SocketIOClient('http://localhost:3001/')
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.socket.on('message', (o) => {
this.setState({msg: this.state.msg.concat(o)})
})
}
handleChange = (e) => {
this.setState({value: e.target.value})
}
handleSubmit = (e) => {
console.log(this.state.value)
this.socket.emit('message', this.state.value)
this.setState({value: ''})
e.preventDefault()
}
render() {
return(
<div>
<ul id="messages">
{
this.state.msg.map((o) => {
return(<li>{o}</li>)
})
}
</ul>
<input id="m" autoComplete="off" value={this.state.value} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>Send </button>
</div>
)
}
}
export default ChatRoom
Alright let's break this down. I am going to explain what's happening here. First in the constructor we have created some state. this.state.value
will hold the current message being written where as this.state.message
will hold all the messages broadcasted by the server side.
constructor(props){
super(props)
this.state = {
value: '',
msg: []
}
}
Then in below lines we setup client side socket.io and listen for broadcasting messages in our client side.
this.socket = SocketIOClient('http://localhost:3001/')
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.socket.on('message', (o) => {
this.setState({msg: this.state.msg.concat(o)})
})
Now in render we added this code block.
<ul id="messages">
{
this.state.msg.map((o) => {
return(<li>{o}</li>)
})
}
</ul>
this is going to render all the broadcasted messages in our view. with all that setup we are ready to set up socket io in the server side.
First of all I am going ot create a server side api. I usually like to do it in the same folder structure. So in the root of my application I create a new folder called api. mkdir api
. You can also do this manually. You can also put this folder where ever you want.
cd api
Now we change directory to this folder and do npm init --yes
I populated my json file like so as shown below.
{
"name": "api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"socket.io": "^2.0.3"
}
}
you can structure your file like this and do npm install
. PLease note that if you don't have nodemon
you can install it by npm install -g nodemon
Now in the server.js file we do the following.
const app = require('express')()
const http = require('http').Server(app)
const io = require('socket.io')(http)
app.get('/', function(req, res){
res.send('good vibes')
})
io.on('connection', function(socket){
console.log('a user connected')
socket.on('message', function(msg){
io.emit('message', msg)
})
})
http.listen(3001, function(){
console.log('listening on *:3001')
})
I am going to explain the socket part. if you have already used socket.io in other project or went over offical documentation you already know how this works.
io.on('connection', function(socket){
console.log('a user connected')
socket.on('message', function(msg){
io.emit('message', msg)
})
})
so socket is listening for the message channel here and emiting back the message to our client side.
And now we can test our application.
go to root of your api
and do npm start
and simmilarly we need to go to the react app root and do the npm start
. To see if the server side is running we can visit http://localhost:3001/
and we will see it prints out good vides.
and now if we go to our http://localhost:3000/ we can see the app in action. So this is the most basic real time app we can build. We will be adding more functionalities and will be creating more complex application using the basic concepts that are covered here.