【问题标题】:ReactJS Chat Websockets emits message twiceReactJS Chat Websockets 两次发出消息
【发布时间】:2021-02-10 16:49:50
【问题描述】:

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

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

【问题讨论】:

    标签: javascript reactjs websocket emit


    【解决方案1】:

    我发现的一些问题:
    chatInput 是一个字符串,在字符串中添加事件监听器感觉很奇怪。它可能会起作用。

    &lt;input&gt; 有一个名为 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>
    )
    

    【讨论】:

    • 'setUserInput' 未定义。我也尝试了你的代码的某些部分,它没有改变任何东西。
    • 在我的代码中定义了 setUserInput,见第 1 行。添加一些控制台日志以查看调用了多少次 useEffect。您可以做的另一个解决方案是确保 chatMessages 中没有具有相同 id 的元素。
    • 是的,但它在渲染方法中显然不可用。
    • 随时使用codesandbox 展示您的代码:)
    【解决方案2】:

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

    我错误地将我的nsSocket.on('chat', (data) =&gt; { 放在另一个nsSocket.on(' 中,在我将它提取到外面后,问题得到了解决。

    【讨论】:

      猜你喜欢
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多