Node.js 无论何时我发送消息,它都会在react中多次显示相同的消息
上面的img说明了这个问题。您也可以检查右下角的控制台 我正在使用socket io react node开发一对一聊天网站,express我正面临这个问题,例如:当我第一次键入hi时,hi显示1次当我键入hii时,它显示2次当我第三次键入jo时,它显示jo 3次我如何修复此问题这是我的反应代码,我的消息在另一端未接收它仅显示在发件人页面上Node.js 无论何时我发送消息,它都会在react中多次显示相同的消息,node.js,reactjs,express,socket.io,chat,Node.js,Reactjs,Express,Socket.io,Chat,上面的img说明了这个问题。您也可以检查右下角的控制台 我正在使用socket io react node开发一对一聊天网站,express我正面临这个问题,例如:当我第一次键入hi时,hi显示1次当我键入hii时,它显示2次当我第三次键入jo时,它显示jo 3次我如何修复此问题这是我的反应代码,我的消息在另一端未接收它仅显示在发件人页面上 import React, { Component } from 'react'; import { Link,Redirect } from 'react
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>
)
}
}
}
这是因为每次发送消息时,都会为套接字分配另一个新回调 移动此部分:
this.socket.on(`${receiverusername}`,(d)=>{
if(this.state[`{receiverusername}`]?.length>=1){
让messageList=this.state[`${receiverusername}`]
this.setState({[`${receiverusername}`]:[…messageList,d]})
}否则{
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(“消息”,(d)=>{
if(this.state[`{d.receiverusername}`]?.length>=1){
让messageList=this.state[`${d.receiverusername}`]
this.setState({[`${receiverusername}`]:[…messageList,d.content]})
}否则{
this.setState({[`${d.receiverusername}`]:[d.content]})
console.log('else Condition store individual messages',
this.state[`${receiverusername}`])
}
})
但是在这个变体中,您没有receiverusername。
所以,您应该从您的服务器发送一般的“消息”事件,作为包含receiverusername的对象
socket.io文档中详细解释了on方法:
在onconnect处理程序中分配onmessage回调的模式记录如下:
它没有显示任何数据,也没有控制台日志记录任何内容这是我的服务器代码连接回调:在组件内,因此它没有挂载rendering@PratikZinjurde对不起,我忘了一件事。请检查更新的答案。你能检查服务器代码吗?如果用户没有将消息发送给其他用户,则会显示消息只有它自己的标签
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")
})
});