ReactJS Chat Websockets 发出消息两次

ReactJS Chat Websockets emits message twice

我有一个聊天组件,它在快乐流程中运行良好,但是当我进入另一个视图(意味着我退出聊天组件)并在聊天组件中返回时,我收到重复的消息。

我将 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>
    );
}

我发现的一些问题:
chatInput是一个字符串,给字符串加事件监听感觉很奇怪。可能有用。

<input> 有一个叫做 onKeyUp 的道具,可能对你很有用。

如果您仍然遇到重复问题,这可能会更简单、更容易找到问题:

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>
)

我发现了问题。与我的想法相反,问题出在我的服务器端。

我把我的 nsSocket.on('chat', (data) => { 错误地放在了另一个 nsSocket.on(' 里面,在我把它取出来之后,问题就解决了。