ReactJS Chat Websockets发出两次消息

piztneat  于 8个月前  发布在  React
关注(0)|答案(2)|浏览(75)

我有一个聊天组件,它在快乐流上工作得很好,但是当我进入另一个视图(意味着我退出聊天组件)并在聊天组件中返回时,我会收到重复的消息。
我将console.log放入由enter事件触发的函数中,但它只显示一次。然而,我认为从内部发出触发了两次,因为在服务器端(nodeJs)我获得了两次数据。
这是我的代码:

function Chat() {     
    let [chatInput, setChatInput] = useState('');   
    let [chatArea, setChatArea] = useState([]);     

    const handleOnChange = (e) => {
        setChatInput(e.target.value) 
    }

    useEffect(() => {                      
        const addTextMessage = (event) => {
            if (event.keyCode === 13 && chatInput.value !== '') {                
                event.preventDefault(); 
                
                socket.emit('chat', {
                    message: chatInput.value
                });                
                                                      
                setChatInput('');              
            }  
        }

        const chatInput = document.querySelector('.chat-input input');
        chatInput.addEventListener("keyup", addTextMessage, false);

        socket.on('chat', (data) => {
            setChatArea(prevInputState => (                    
                [...prevInputState, <section key={prevInputState.length}>{data.sender}: {data.message}</section>]
            ))                                     
        })  

        return () => {            
            chatInput.removeEventListener("keyup", addTextMessage, false);                
            socket.off('chat');        
        };  

    }, []);

    return (
        <React.Fragment>                                        
            <section className="chat-room">
                <div className="chat-area">
                    {chatArea}   
                </div>
                <div className="chat-input">
                    <input value={chatInput} onChange={handleOnChange} type="text" />
                </div>
            </section>         
        </React.Fragment>
    );
}
bsxbgnwa

bsxbgnwa1#

我发现的一些问题:

chatInput是一个字符串,给字符串添加事件监听器感觉怪怪的。可能有用。

<input>有一个名为onKeyUp的 prop ,它可能对您非常有用。
这可能更简单,更容易找到问题,如果你仍然得到重复:

const [userInput, setUserInput] = useState("")
const [chatMessages, setChatMessages] = useState([])

function trySendMessage(event) {
   // Send message if last key was ENTER and we got some text
   if (event.keyCode === 13 && userInput !== "") {
     event.preventDefault();
     socket.emit("chat", {
       message: chatInput,
     })
     setChatInput("");
   }
}

// This effect only changes the state
// Notice I'm not storing the rendered result in state,
// Instead I handle rendering below in the rendering section
useEffect(() => {
  socket.on('chat', (newMessage) => setChatArea([...chatMessages, newMessage])
  return () => socket.off('chat')
}, [])

return (
   <section>
     {
       chatMessages.map(message => (
         <div key={message.id}>{message.name}: {message.body})</div>
       )
     }
     <input
       value={userInput}
       onChange={(e) => setUserInput(e.target.value)}
       onKeyUp={trySendMessage}
     />
   </section>
)
fv2wmkja

fv2wmkja2#

我发现问题了。与我所想的相反,问题来自我的服务器端。
我把我的nsSocket.on('chat', (data) => {错误地放在另一个nsSocket.on('里面,在我把它提取出来之后,问题就解决了。

相关问题