【发布时间】:2020-03-06 19:26:56
【问题描述】:
我正在使用 socket.io 和 react.js。我需要为套接字声明一些事件处理程序,另外由于我正在使用一些模块,我不能使用经典的类组件,因此我将函数与钩子一起使用。问题是使用 useEffect 钩子初始化事件处理程序会导致每次发生新渲染时重新声明套接字事件处理程序,因此,每个事件都会与一堆事件处理程序连接,而不是只有一个,这会导致多次调用所需的事件发生时的事件处理程序。有办法让 useEffect 只运行一次;将一个空数组作为第二个参数传递给它(这使它像类组件中的构造函数)。这可以防止对事件处理程序的多次调用,但是,这也可以防止事件处理程序访问组件的最新状态。有没有办法同时实现?
var socket = io('http://localhost:10000');
const [var, setvar] = useState(0);
useEffect(() => {
socket.on('event', function(data) { //event handler function
console.log(var);
});
}, []);
为了进一步解释,上面的代码每个事件只调用一次事件处理函数,但它总是输出 var 的初始状态,即 0。另一方面,如果 [] 参数被删除,处理程序将输出var 的当前值,但它会多次输出,因为每次渲染都有一个新的事件处理程序连接到套接字,所以输出的数量取决于在该事件之前发生的渲染次数。
【问题讨论】:
-
从
useEffect回调中返回一个将调用socket.off的函数。这将导致组件在卸载时取消注册。如果您只想在应用程序的上下文中存在 1 个到套接字的连接,您应该编写一个 Context 并在您的组件中使用它。
标签: javascript reactjs socket.io