每当我发送消息时,它都会在反应中多次显示相同的消息
Posted
技术标签:
【中文标题】每当我发送消息时,它都会在反应中多次显示相同的消息【英文标题】:Whenever i send msg it is showing same message multiple times in react 【发布时间】:2021-06-11 04:31:39 【问题描述】:上面的img显示了问题。您也可以检查右下角的控制台 我正在使用 socket io react 节点开发一对一的聊天网站,表达我面临这个问题,例如:当我先输入 hi 然后 hi 显示 1 次时,当我输入 hii 时,它显示 2 次,当我第三次输入 jo it显示 jo 3 次我该如何解决这个问题这是我的反应代码另外我的消息在另一端没有收到它只显示在发件人页面上
import React, Component from 'react';
import Link,Redirect from 'react-router-dom';
import UserService from "../services/userservice";
import getUsersFriend from "../services/messageservice";
import io from "socket.io-client";
const SOCKET_IO_URL = "http://localhost:4000/";
export default class Messages extends Component
constructor(props)
super(props)
this.socket = io(SOCKET_IO_URL)
this.state =
currentUser: UserService.getCurrentUser(),
isLoading:false,
userdetails:[],
show:false,
username:'',
message:'',
socketConnected:false,
messages:[]
;
this.onTextboxChangeMessage = this.onTextboxChangeMessage.bind(this)
componentDidMount()
const currentUser=this.state
this.fetchUser()
this.socket.on('connect',()=>
this.setState( socketConnected : true)
// console.log("connection")
)
async fetchUser()
try
const currentUser = this.state
console.log(currentUser)
const data = userid : currentUser.user._id
console.log(data)
let user = await getUsersFriend(data)
this.setState( userdetails: user );
// console.log(user)
catch(err)
console.log(err)
showMessageSpace(elementusername)
this.setState(
show: true,
username:elementusername
);
onTextboxChangeMessage(e)
this.setState( message:e.target.value)
SendMessage(e,senderid,receiverusername,message,senderusername)
e.preventDefault();
e.stopPropagation()
console.log('event', e)
const messages =this.state
if(this.state.socketConnected)
console.log('if condition test',senderid,receiverusername,message,senderusername )
this.socket.emit('send',senderid,receiverusername,message,senderusername);
this.socket.on(`$receiverusername`, (d)=>
if(this.state[`$receiverusername`]?.length >= 1 )
let messageList = this.state[`$receiverusername`]
this.setState([`$receiverusername`]:[...messageList,d])
else
this.setState([`$receiverusername`]:[d])
console.log('else Condition store individual messages', this.state[`$receiverusername`])
this.setState( message:'' )
render()
const currentUser ,isLoading,userdetails,message,messages = this.state;
// console.log(messages)
if (isLoading)
return (<div><p>Loading...</p></div>);
if(!currentUser)
return(
<div>
<Redirect to='/login' />
</div>
)
else
return(
<div>
<h1>Messages</h1>
<div>
<p>Users</p>
' '
<ul className="collection">
userdetails.map((element) =>
return(
<div key=element._id>
<li><Link to=`/dashboard/profile/:$element._id`>element.username</Link>' '<input
type="button"
id=element._id
value="Message"
onClick=this.showMessageSpace.bind(this,element.username) ></input></li>
</div>
);
)
</ul>
' '
</div>
' '
<Link to="/dashboard">Dashboard</Link>
' '
<div>
this.state.show &&
(<div>
<h2>Username : ' 'this.state.username</h2>
' '
<div>
<h3>Body</h3>
<div>
<ul>
/* this.state[`$this.state.username`]?.map((msg,key) => */
this.state.username?.length > 0 && this.state[`$this.state.username`]?.map((msg,key) =>
return(<li key=key>msg.senderusername<span>' 'msg.message</span></li>);
)
</ul>
</div>
</div>
' '
<div>
' '
<input
type="text"
name="message"
value=message
onChange=this.onTextboxChangeMessage
></input>
<button className='btn btn-info' onClick=(e)=> this.SendMessage(e,currentUser.user._id,this.state.username,this.state.message,currentUser.user.username)>Send</button>
</div>
' '
</div>)
</div>
</div>
)
服务器代码:
io.on('connection', (socket) => /* socket object may be used to send specific messages to the new connected client */
console.log('connection established',socket.id);
socket.on('send', (data)=>
console.log("Receive data from single username",data)
io.emit('message',data)
socket.on('message',data =>
console.log("private")
io.to(data.receiverid).emit('message',data)
)
);
socket.on('disconnected',()=>
console.log("disconnect")
)
);
【问题讨论】:
【参考方案1】:这是因为您每次发送消息时都会为套接字分配另一个新回调。
移动这部分:
this.socket.on(`$receiverusername`, (d)=>
if(this.state[`$receiverusername`]?.length >= 1 )
let messageList = this.state[`$receiverusername`]
this.setState([`$receiverusername`]:[...messageList,d])
else
this.setState([`$receiverusername`]:[d])
console.log('else Condition store individual messages',
this.state[`$receiverusername`])
进入 onconnect 回调:
this.socket.on('connect',()=>
this.setState( socketConnected : true)
this.socket.on("message", (d)=>
if(this.state[`$d.receiverusername`]?.length >= 1 )
let messageList = this.state[`$d.receiverusername`]
this.setState([`$receiverusername`]:[...messageList,d.content])
else
this.setState([`$d.receiverusername`]:[d.content])
console.log('else Condition store individual messages',
this.state[`$receiverusername`])
)
但在这个变体中,您没有接收者用户名。 所以你应该从你的服务器发送一般的“消息”事件作为包含接收者用户名的对象。
socket.io 文档中详细解释了 on 方法:https://socket.io/docs/v3/listening-to-events/
这里记录了在 onconnect 处理程序中分配 onmessage 回调的模式:
https://socket.io/get-started/chat/#Broadcasting
【讨论】:
它没有显示任何数据,也没有控制台记录任何东西 onconnect 回调:在 componentdidmount 内,我认为它没有渲染 @PratikZinjurde 抱歉,我忘了一件事。请检查更新的答案。 你能检查服务器代码吗,用户没有将消息发送给其他用户,它只显示在自己的标签上 在里面我尝试发送receiverid和senderid,但其他用户没有收到消息以上是关于每当我发送消息时,它都会在反应中多次显示相同的消息的主要内容,如果未能解决你的问题,请参考以下文章
当用户对消息做出反应时,机器人会在 discord.js 中发送另一条消息