我无法在后续点击后发送消息,如果我第一次点击按钮是向服务器发送消息,之后就不向服务器发送消息。
import { useEffect, useState, useRef } from "react";
import Header from "../src/Components/Header";
import ChatHistory from "../src/Components/ChatHistory";
import ChatArea from "../src/Components/ChatArea";
function App() {
const [messages, setMessages] = useState([]);
const testValue = { messages, setMessages };
const socket = useRef(null);
const renderCount = useRef(0);
const sendMessage = (msg = "test") => {
if (socket.current) {
socket.current.send(msg);
}
addMessages(msg);
};
const addMessages = (msg) => {
setMessages((prev) => [...prev, msg]);
};
useEffect(() => {
socket.current = new WebSocket("ws://localhost:8001/ws");
socket.current.onmessage = (msg) => {
addMessages(msg);
};
}, []);
useEffect(() => {
return () => {
if (socket.current) {
socket.current.close();
}
};
}, [socket]);
console.log("i am rendering");
return (
<>
<Header />
<ChatHistory chatHistory={messages.current} />
<div>
<button onClick={sendMessage}>Send</button>
</div>
</>
);
}
export default App;
上面提到的一个是我的代码,当第一次点击发送按钮时,它会触发向服务器发送消息,随后再次点击它不会向服务器发送消息。需要帮助。
答案 0 :(得分:0)
您的第二个 useEffect
实际上在第一次渲染后关闭了连接,这是不必要的。
此外,您实际上并不需要将套接字实例保存在 ref 中,通常您只需要一个实例:
const socket = new WebSocket("ws://localhost:8001/ws");
function App() {
const [messages, setMessages] = useState([]);
const addMessages = (msg) => {
setMessages((prev) => [...prev, msg]);
};
const sendMessage = (msg = "test") => {
socket.send(msg);
addMessages(msg);
};
// Setup
useEffect(() => {
socket.current.onmessage = addMessages;
}, []);
// Runs on App unmount, means on closing the application
useEffect(() => {
return () => {
socket.close();
};
}, []);
return (
<>
<Header />
<ChatHistory chatHistory={messages.current} />
<div>
<button onClick={sendMessage}>Send</button>
</div>
</>
);
}
答案 1 :(得分:0)
useEffect(() => {
return () => {
if (socket.current) {
socket.current.close();
}
};
}, [socket]);
每当套接字发生变化时,你就关闭它
尝试在定义套接字的同一个 useEffect 中卸载
useEffect(() => {
if (!socket.current) {
socket.current = new WebSocket("ws://localhost:8001/ws");
socket.current.onmessage = (msg) => {
addMessages(msg);
};
}
return () => {
if (socket.current) {
socket.current.close();
}
};
}, [socket]);
注意 useRef 不是这种情况的最佳选择,请改用 useState