admin管理员组文章数量:1201410
Body: I’m building a real-time chat application using the MERN stack, where the frontend uses React, the backend uses Node.js with WebSocket, and MongoDB stores chat history.
Problem: When I send a chat message from one browser tab, it successfully broadcasts to the WebSocket server and renders in that tab. However, in other tabs where the chat is open, the new message is not rendered until I refresh or rejoin the chat.
Here’s what I’ve tried:
Ensuring that the WebSocket connection broadcasts messages to all clients. Using React’s useEffect to listen for onmessage events and update the state (setMessages). Using a useRef to hold the latest messages and avoid stale closures. Ensuring WebSocket connections are established and open in all tabs.
const { ws, isReady } = useWebSocket();
const navigate = useNavigate();
const { session } = useContext(createSessionContext);
const [chat, setChat] = useState<string>("");
const [messages, setMessages] = useState<ChatMessage[]>([]);
const location = useLocation();
const messageRef = useRef<ChatMessage[]>([]);
useEffect(() => {
if (Array.isArray(location.state) && location.state.length > 0) {
setMessages(location.state);
messageRef.current = location.state;
}
}, [location.state]);
useEffect(() => {
if (!session) {
navigate("/");
return;
}
if (isReady && ws?.readyState === WebSocket.OPEN) {
ws.onmessage = (event: MessageEvent) => {
const data = JSON.parse(event.data);
const newMessage: ChatMessage = {
name: data.payload.name,
message: data.payload.message,
upvotes: [],
chatId: data.payload.chatId,
};
messageRef.current = [...messageRef.current, newMessage];
setMessages([...messageRef.current]);
};
ws.onerror = (e) => {
console.error("WebSocket error:", e);
};
}
return () => {
if (ws) {
ws.onmessage = null;
ws.onerror = null;
}
};
}, [ws, isReady, session, navigate]);
const SendChat = () => {
if (isReady && ws && ws.readyState === WebSocket.OPEN && chat.trim() !== "") {
ws.send(
JSON.stringify({
type: "SEND_MESSAGE",
payload: {
sessionId: session,
message: chat,
},
})
);
setChat("");
}
};
return (
<div className="bg-slate-400 max-w-screen h-screen">
<div className="max-w-screen-md mx-auto p-10 relative top-20 flex flex-col bg-slate-600 text-white rounded-md">
<h1 className="text-center">Chat</h1>
<div className="flex border border-white justify-between p-2 rounded-md mt-2">
<div className="border-collapse">
<h2 className="ml-1.5">All Chats</h2>
<div className="border-collapse pt-5 pb-5">
{messages.length > 0 ? (
<div>
{messages.map((message, index) => (
<div
className="flex font-semibold bg-slate-900 pt-1 pb-1 mb-2.5 justify-between rounded-md"
key={message.chatId}
>
<div className="flex gap-2">
<div className="text-slate-200">{message.name}:</div>
<div className="text-slate-200">{message.message}</div>
</div>
<div className="flex items-center gap-2.5">
<div className="text-white font-bold cursor-pointer border rounded-full p-1">
<FaArrowUpLong />
</div>
<div>{message.upvotes.length}</div>
</div>
</div>
))}
</div>
) : (
<div className="text-slate-200">No messages yet</div>
)}
</div>
<input
className="bg-slate-800 p-1.5 mr-1.5 rounded-md outline-none"
type="text"
placeholder="chat"
value={chat}
onChange={(e: ChangeEvent<HTMLInputElement>) => setChat(e.target.value)}
/>
<button onClick={SendChat} className="bg-slate-800 rounded-md p-1.5">
Send
</button>
</div>
</div>
</div>
</div>
);
}; ````````
本文标签: reactjsReact WebSocket Chat Messages Not Rendering in Other Tabs Until RejoinedStack Overflow
版权声明:本文标题:reactjs - React WebSocket Chat: Messages Not Rendering in Other Tabs Until Rejoined - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738564119a2099809.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论