­2019-03-13 23:47:53
Socket.io
­, 2019-03-13 23:47:53

How to receive messages in a React component using socket.io?

Everywhere in the socket.io examples, jquery, all sorts of ajaxes are used. And I could not find a good example of receiving messages in react.
I checked my server.js using the socketserve.io site:
5c89673446816328879776.png
As you can see, the message was sent successfully. server.js
code :

const app = require('express')()
const http = require('http').Server(app)
const io = require('socket.io')(http)

const port = 8000

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/public/index.html')
})

io.on('connection', client => {
  let addedUser = false

  // При подключении с помощью componentDidMount делаю emit эвента 'new user'
  client.on('new user', username => {
    if (addedUser) return

    client.username = username
    addedUser = true
    console.log(`${client.username} joined`)
    client.broadcast.emit('user join', { username: client.username })
  })

  // Отправка сообщений
  client.on('new message', data => {
    console.log('MSG: ', data)
    io.emit('new message', { message: data })
  })

  client.on('disconnect', () => {
    console.log(`${client.username} has disconnected`)
  })
})

http.listen(port, () => {
  console.log(`listening on *:${port}`)
})

Component:
import React, { Component } from 'react'
import { createGlobalStyle } from 'styled-components'
import openSocket from 'socket.io-client'
// import SocketIOClient from 'socket.io-client'

// const socket = SocketIOClient('http://localhost:8000/')

const socket = openSocket('http://localhost:8000/')
const name = 'Jeff'

const GlobalStyle = createGlobalStyle`
  body {
    background-color: #1e1f26;
    color: #DBDBD4;
  }
  * {
    font-family: 'Roboto Condensed', sans-serif;
  }
`

class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      text: '',
      messages: []
    }
  }

  componentDidMount = () => {
    socket.emit('new user', name)
  }


  handleChange = e => {
    this.setState(state => ({ ...state, text: e.target.value }))
  }

  handleSubmit = e => {
    e.preventDefault()
    console.log('submited')
    this.setState(state => ({ ...state, text: '' }))
    socket.emit('new message', this.state.text)
  }

  render() {

    return (
      <div>
        <GlobalStyle />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.handleChange} value={this.state.text} />
        </form>
        <div>
          {this.state.messages.map((message, index) => (
            <p key={index}>{message}</p>
          ))}
        </div>
      </div>
    )
  }
}

export default App

Code for receiving messages:
socket.on('new message', data => {
  this.setState(state => ({
    ...state,
    text: '',
    messages: [...state.messages, data.message]
  }))
})

Where to put this code? in render() ?
Inserted into render:
(I tried to insert into handleSubmit , and into componentDidUpdate . One fig either does not work or is crooked, as in the last screenshot)
5c896ae153dfb591443336.png
And it works incredibly crookedly:
(As you can see, I sent only 2 messages, but many more were sent)
5c896af87e0d1264994427.png
How to use Socket.io with React? How to get a new message from another client so that it doesn't get rendered a million hundred times?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2019-03-13
@640

Where to put this code? in render() ?

In componentDidMount.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question