我使用带React钩子的简单聊天应用程序工作。 在第二个useEffect 中,我需要将新消息添加到其余消息中,以便能够在聊天中显示所有消息。现在,仅在从数组的长度中将useEffect称为x2之后,才可以附加消息。例如:在第四条消息中,UseEffect将在数组完成之前执行8次。
通知:在useEffect中,我两次设置了AllMessages,但是只有一个正在执行,这取决于它是否是发件人的收件者(所以我不认为这是问题所在)
function Chat() {
const [message, setMessage] = useState("");
const [userName] = useState(
JSON.parse(atob(localStorage.getItem("token").split(".")[1])).name
);
const [userTyping, setUserTyping] = useState(null);
const [allMessages, setAllMessages] = useState([]);
useEffect(() => {
socket.emit("join", userName);
socket.on("chat-message", data => {
toast(`Hello ${data}`);
});
socket.on("user-joined", data => {
toast(`${data} joined the chat`);
});
}, [userName]);
useEffect(() => { // the problem is here
function handleAllMessages(data) {
setAllMessages([...allMessages, data]);
console.log(allMessages);
}
socket.on("broadcast-message", data => {
handleAllMessages(data);
});
socket.on("my-message", data => {
data["userName"] = "You";
handleAllMessages(data);
});
}, [allMessages]);
useEffect(() => {
socket.on("who-typing", data => {
setUserTyping(data);
setTimeout(() => {
setUserTyping(null);
}, 2500);
});
}, [userTyping]);
useEffect(() => {
socket.on("user-disconnected", data => {
toast(`${data} left the chat`);
});
}, []);
function handleChat(e) {
e.preventDefault();
if (message.trim() === "") return toast.warn("not valid message");
socket.emit("user-message", message, userName);
setMessage("");
}
function handleChange(e) {
setMessage(e.target.value);
socket.emit("typing", userName);
}
return (...
答案 0 :(得分:0)
第二个useEffect
会被执行多次(实际上我想无限地这样做)的原因是因为您告诉它每次allMessages
更改都会执行一次,因为它在数组中- useEffect
的第二个参数。
传递带有allMessages
的数组将导致useEffect
每次allMessages
更改时都重新运行,这实际上是您在useEffect
内所做的操作您正在调用handleAllMessages
函数。
答案 1 :(得分:0)
在钩子中正确设置setAllMessages的方法(在这种情况下)是像这样传递oldArray ...
WebClient client = WebClient.create("www.google.com");
ObjectMapper mapper = new ObjectMapper();
client.get()
.retrieve()
.bodyToMono(String.class)
.map(rawBody -> {
try {
return mapper.readValue(rawBody, Response.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot deserialize string: " + rawBody);
}
});
在使用效果内,将空数组作为第二个参数传递,而不是setAllMessages(allMessages => [...allMessages, data]);
此问题已解决