React Hook(使用状态)与套接字io结合时不工作



我快疯了。我真的不明白为什么下面的不起作用。我开始反应。我正在尝试从服务器获取数据,并在渲染前加载我的状态。插座";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();
//
}, []);

控制台捕获

你能帮我吗?我没有发现类似的情况。谢谢

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

您的代码运行良好,您只需要将日志语句放在它们不有用的地方。

updates是一个局部常量。它永远不会改变,这不是setUpdates想要做的。useEffect中的console.log语句将只引用responseupdates在第一次渲染时的值。

当您调用setUpdates时,您要求react重新提交组件。在这个新的渲染中,将创建一个新的局部常量,它将获得新的值。新渲染中的代码可以使用此值,但上一次渲染中的编码不能。如果你想验证它是否使用新值重新报价,那么把你的日志语句放在组件的主体中:

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((中定义套接字常量它将在每次套接字更新后呈现useEffect钩子。

const [update,setupdate] = useState()
useEffect(()=>{ 
const socket = io("http://localhost:3001");
socket.on("send data", function (data_from_socket) {
setupdate(data_from_socket);
})
})

别忘了不要在使用中使用[]有效

最新更新