node.jsreactjsreact-nativesocket.iosocket.io-1.0

socket.io client receiving multiple calls to same event in react native


Whenver the user login into the application. he joins to its own userId in server via

socket.join(uid)

whereas the nodejs endpoint looks like

router.post("/secured/postmessage", (req,res)=>{
  const { message, receiverId } = req.body;

 io.to(receiverId).emit("newMessage", {
      msgBody: message,
      sender: req.currentUser,
    });
})

now the RN part:

Chat screen functional Component looks like

export default function Chat({ navigation }) {

//receiveing the socket as props from previous screen
  const { contact, socket } = navigation.state.params;
  // console.log("in conversation contact is ", contact);


  const [data, setData] = useState([
    {
      id: 8,
      date: "9:50 am",
      type: "in",
      message: "Lorem ipsum dolor sit a met",
    },
  ]);

//this gets fired multiple times <--------
socket.on("newMessage", ({ msgBody, sender }) => {
    setData((oldMessages) => [...oldMessages, msgBody]);
  });

//handleSubmit gets fired when user types message and press SEND
const handleSubmit(){
//sending the post request to server with message
 axios.post(baseUrl + "/secured/postmessage", {
    message: message,
    receiverId: contact._id,
    })
}
return(
  ...
  )

whereas the nodejs endpoint looks like

router.post("/secured/postmessage", (req,res)=>{
 io.to(receiverId).emit("newMessage", {
      msgBody: messageResult,
      sender: req.currentUser,
    });
})

socket.on('newMessage') in Chat screen is getting fired multiple times, I dont know why


Solution

  • I think you can try adding socket event handler only when your Chat component mounted.
    In functional component, you can use React.useEffect().

    refer to below

    React.useEffect(() => {
        socket.on("newMessage", ({ msgBody, sender }) => {
            setData((oldMessages) => [...oldMessages, msgBody]);
        });
    },[]);