与 socket io 结合使用时,React Hook(usestate)不起作用
React Hook (usestate ) not working when combined with socket io
我快疯了。我真的不明白为什么下面的不起作用。我从反应开始。
我正在尝试从服务器获取 datas 并在渲染之前加载我的状态。
套接字“fromAPI”没问题,这只是一个计时器。
套接字“lobbyUpdate”不工作,我正在从数据库中获取数据。
import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:2500";
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
socket.on('lobbyUpdate', datas => {
console.log(updates) // Nothing
setUpdates(datas)
console.log(datas) // datas are displayed
console.log(updates) // nothing is displayed
})
// CLEAN UP THE EFFECT
return () => socket.disconnect();
//
}, []);
console-capture
你能帮帮我吗?我没有找到类似的案例。
谢谢
您的代码运行良好,您只是将日志语句放在了无用的地方。
updates
是局部常量。它永远不会改变,这不是 setUpdates
想要做的。 useEffect 中的 console.log 语句只会引用 response
和 updates
在第一次渲染时的值。
当您调用 setUpdates
时,您要求做出反应以重新呈现组件。在那个新渲染器上,将创建一个新的局部常量,并将获得新值。新渲染中的代码可以使用这个值,但以前渲染中的代码不能。如果您想验证它是否正在使用新值重新呈现,请将您的日志语句放入组件的主体中:
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
console.log("rendering with: ", response, updates);
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
socket.on('lobbyUpdate', datas => {
setUpdates(datas)
})
// CLEAN UP THE EFFECT
return () => socket.disconnect();
}, []);
useEffect
中的 updates
引用了 初始渲染 中的值,而不是当前正在渲染的值。要修复它,要么使用 refs 而不是(或除了)state,或者在每次更新更改时使用 useEffect
运行:
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
const socketRef = useRef();
// Create the socket
// and add the API listener:
useEffect(() => {
socketRef.current = socketIOClient(ENDPOINT);
socketRef.current.on("FromAPI", setResponse);
return () => socketRef.current.disconnect();
}, []);
useEffect(() => {
const handleLobbyUpdate = (datas) => {
console.log(updates); // this will now display the current data
setUpdates(datas);
};
socketRef.current.on('lobbyUpdate', handleLobbyUpdate);
return () => {
socketRef.current.off('lobbyUpdate', handleLobbyUpdate);
}
}, [updates]);
请记住,状态设置器是异步的,因此您不会在调用 setUpdates
后立即看到 updates
变量发生变化 - 您必须等到下一次呈现 updates
成为人口。
我快疯了。我真的不明白为什么下面的不起作用。我从反应开始。 我正在尝试从服务器获取 datas 并在渲染之前加载我的状态。 套接字“fromAPI”没问题,这只是一个计时器。 套接字“lobbyUpdate”不工作,我正在从数据库中获取数据。
import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:2500";
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
socket.on('lobbyUpdate', datas => {
console.log(updates) // Nothing
setUpdates(datas)
console.log(datas) // datas are displayed
console.log(updates) // nothing is displayed
})
// CLEAN UP THE EFFECT
return () => socket.disconnect();
//
}, []);
console-capture
你能帮帮我吗?我没有找到类似的案例。 谢谢
您的代码运行良好,您只是将日志语句放在了无用的地方。
updates
是局部常量。它永远不会改变,这不是 setUpdates
想要做的。 useEffect 中的 console.log 语句只会引用 response
和 updates
在第一次渲染时的值。
当您调用 setUpdates
时,您要求做出反应以重新呈现组件。在那个新渲染器上,将创建一个新的局部常量,并将获得新值。新渲染中的代码可以使用这个值,但以前渲染中的代码不能。如果您想验证它是否正在使用新值重新呈现,请将您的日志语句放入组件的主体中:
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
console.log("rendering with: ", response, updates);
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
socket.on('lobbyUpdate', datas => {
setUpdates(datas)
})
// CLEAN UP THE EFFECT
return () => socket.disconnect();
}, []);
useEffect
中的 updates
引用了 初始渲染 中的值,而不是当前正在渲染的值。要修复它,要么使用 refs 而不是(或除了)state,或者在每次更新更改时使用 useEffect
运行:
function Lobby() {
const [response, setResponse] = useState("")
const [updates, setUpdates] = useState([])
const socketRef = useRef();
// Create the socket
// and add the API listener:
useEffect(() => {
socketRef.current = socketIOClient(ENDPOINT);
socketRef.current.on("FromAPI", setResponse);
return () => socketRef.current.disconnect();
}, []);
useEffect(() => {
const handleLobbyUpdate = (datas) => {
console.log(updates); // this will now display the current data
setUpdates(datas);
};
socketRef.current.on('lobbyUpdate', handleLobbyUpdate);
return () => {
socketRef.current.off('lobbyUpdate', handleLobbyUpdate);
}
}, [updates]);
请记住,状态设置器是异步的,因此您不会在调用 setUpdates
后立即看到 updates
变量发生变化 - 您必须等到下一次呈现 updates
成为人口。