3 回答

TA貢獻2080條經驗 獲得超4個贊
您的updates內部正在引用初始 renderuseEffect的值,而不是當前正在呈現的值。要修復它,要么使用 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]);
請記住,狀態設置器是異步的,因此您不會updates在調用后立即看到變量發生變化setUpdates- 您必須等到下一次渲染才能updates填充。

TA貢獻1878條經驗 獲得超4個贊
您的代碼運行良好,您只是將日志語句放在它們無用的地方。
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();
}, []);

TA貢獻1893條經驗 獲得超10個贊
您必須在 useEffect() 中定義套接字常量,它將在每次套接字更新后呈現 useEffect 掛鉤。
const [update,setupdate] = useState()
useEffect(()=>{
const socket = io("http://localhost:3001");
socket.on("send data", function (data_from_socket) {
setupdate(data_from_socket);
})
})
并且不要忘記不要在 useEfect 中使用 []
添加回答
舉報