skip to Main Content

So I am creating a real time chatting app using react , redux , node , express and socket.io my code is working without the addMessage action and even if I change it to something like […messages,message] and define messages using useState , it is still showing the error.

this is my code for client side where error is occurring .

import Header from "./Header";
import MessageBox from "./MessageBox";
import MessageBody from "./MessageBody";
import {addMessage} from "../actions"
import { useEffect,useState } from "react";
import { connect } from "react-redux";
import io from 'socket.io-client';

let socket;

const Chat = ({name,addMessage}) => {
    const [message,setMessage] = useState('');
    const ENDPOINT = 'localhost:5000';

    useEffect(()=>{
        socket =io(ENDPOINT);
        socket.emit('join',{name},()=>{
        })
        return ()=>{
            socket.disconnect();
            socket.off();
        }
    },[name]);

    useEffect(()=>{
        socket.on('message',(message)=>{
            addMessage(message)  
            console.log(message);
        });
        return ()=>{
            socket.off();
        }
    });

    const sendMessage = (event)=>{
        event.preventDefault();
        if(message){
            socket.emit('sendMessage',message,()=>setMessage(''))
        }
    }
    
    return (
        <div style={{backgroundColor:"#414a4c"}}>
            <Header/>
            <MessageBody name={name}/>
            <MessageBox message={message} setMessage={setMessage} sendMessage={sendMessage}/>
        </div>
    )
}

const mapStateToProps =(state)=>{
    return{
        name : state.enteredName
    }
}


export default connect(mapStateToProps,{addMessage})(Chat)

this is messageBox component

const MessageBox = ({message,setMessage,sendMessage}) => {

    return (
        <section className="bg-dark text-light p-1" style={style}>
        <div className="container">
        <div className="d-flex justify-content-around align-items-center">
            <div className="input-group news-input">
                <input type="text" className="form-control"
                value={message}
                onChange={({ target: { value } }) => setMessage(value)}
                placeholder="Write Your Messages Here"
                onKeyPress={(e)=>e.key==='Enter'&& sendMessage(e) }
                />
            </div>
            <i className="bi bi-telegram ps-2 pb-1" style={{fontSize:"40px"}}
            onClick={(e)=> sendMessage(e)}
            >
            </i>
        </div>
        </div>
    </section>
    )
}
const style = {
    position : "fixed",
    bottom: "0px",
    width:"100%"
}


export default MessageBox

this is the server side code

const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const {addUser,removeUser,getUser,getAllUsers} = require('./users');
corsOptions={
    cors: true,
    origins:["http://localhost:3000"],
}

const PORT = process.env.PORT || 5000;

const router = require('./router');


const app = express();
const server = http.createServer(app);
const io = socketio(server, corsOptions);

io.on('connection',(socket)=>{
    socket.on('join',({name},callback)=>{
        const {error,user} = addUser({id:socket.id,name});
        if(error)return callback(error);

        socket.emit('message',{user:'admin',text:`${user.name} welcome to the chat.`});
        socket.broadcast.emit('message',{user:'admin',text:`${user.name} has joined the chat`})

        socket.join(user);
        callback();
    })

    socket.on('sendMessage',(message)=>{
        const user = getUser(socket.id);
        io.emit('message',{user:user.name,text:message});
    });


    socket.on('disconnect',()=>{
        console.log("user just left");
        socket.broadcast.emit('message',{user:'admin',text:`${user.name} has left the chat`})
    })
})


app.use(router);

server.listen(PORT,()=>console.log(`The server is running on ${PORT}`));

the complete code is present on : < https://github.com/Pramil01/Globe-Chat.git>

2

Answers


  1. Chosen as BEST ANSWER

    The main issue was in the chatbox component , where I used useState and it was causing rerenders , once removing the code is now working properly.


  2. You have to specify

    useEffect(()=>{
            socket.on('message',(message)=>{
                addMessage(message)  
                console.log(message);
            });
            return ()=>{
                socket.off();
            }
        }, [] <- dependency array);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search