所以我有这个奇怪的错误,需要帮助确定它的来源。
为了更好地说明该错误,我进行了截屏,您可以在此处找到https://www.youtube.com/watch?v=MuXOfbYB_CI
说明:您在视频中看到的是我使用我的dart记分器应用程序,其中左侧窗口是输入掷球的控制器,右侧窗口是记分板。开始游戏后,网站将通过websockets重定向到控制器和计分板。
因此,接下来我要通过单击相应的按钮来结束游戏,然后立即以相同的方式开始新游戏。
然后,当通过控制器输入第一个掷球时,将发生错误。
两个站点(控制器和记分板均抛出此错误):
QueryData.ts:445 Uncaught TypeError: Cannot read property 'refetch' of undefined
at QueryData._this.obsRefetch (QueryData.ts:445)
at Socket.<anonymous> (ControllerPage.jsx:24)
at Socket.push../node_modules/socket.io-client/node_modules/component-emitter/index.js.Emitter.emit (index.js:133)
at Socket.push../node_modules/socket.io-client/lib/socket.js.Socket.onevent (socket.js:278)
at Socket.push../node_modules/socket.io-client/lib/socket.js.Socket.onpacket (socket.js:236)
at Manager.<anonymous> (index.js:21)
at Manager.push../node_modules/socket.io-client/node_modules/component-emitter/index.js.Emitter.emit (index.js:133)
at Manager.push../node_modules/socket.io-client/lib/manager.js.Manager.ondecoded (manager.js:345)
at Decoder.<anonymous> (index.js:21)
at Decoder.push../node_modules/socket.io-parser/node_modules/component-emitter/index.js.Emitter.emit (index.js:133)
at Decoder.push../node_modules/socket.io-parser/index.js.Decoder.add (index.js:251)
at Manager.push../node_modules/socket.io-client/lib/manager.js.Manager.ondata (manager.js:335)
at Socket.<anonymous> (index.js:21)
at Socket.push../node_modules/component-emitter/index.js.Emitter.emit (index.js:145)
at Socket.push../node_modules/engine.io-client/lib/socket.js.Socket.onPacket (socket.js:461)
at WS.<anonymous> (socket.js:278)
at WS.push../node_modules/component-emitter/index.js.Emitter.emit (index.js:145)
at WS.push../node_modules/engine.io-client/lib/transport.js.Transport.onPacket (transport.js:149)
at WS.push../node_modules/engine.io-client/lib/transport.js.Transport.onData (transport.js:141)
at WebSocket.ws.onmessage (websocket.js:160)
QueryData._this.obsRefetch @ QueryData.ts:445
(anonymous) @ ControllerPage.jsx:24
push../node_modules/socket.io-client/node_modules/component-emitter/index.js.Emitter.emit @ index.js:133
push../node_modules/socket.io-client/lib/socket.js.Socket.onevent @ socket.js:278
push../node_modules/socket.io-client/lib/socket.js.Socket.onpacket @ socket.js:236
(anonymous) @ index.js:21
push../node_modules/socket.io-client/node_modules/component-emitter/index.js.Emitter.emit @ index.js:133
push../node_modules/socket.io-client/lib/manager.js.Manager.ondecoded @ manager.js:345
(anonymous) @ index.js:21
push../node_modules/socket.io-parser/node_modules/component-emitter/index.js.Emitter.emit @ index.js:133
push../node_modules/socket.io-parser/index.js.Decoder.add @ index.js:251
push../node_modules/socket.io-client/lib/manager.js.Manager.ondata @ manager.js:335
(anonymous) @ index.js:21
push../node_modules/component-emitter/index.js.Emitter.emit @ index.js:145
push../node_modules/engine.io-client/lib/socket.js.Socket.onPacket @ socket.js:461
(anonymous) @ socket.js:278
push../node_modules/component-emitter/index.js.Emitter.emit @ index.js:145
push../node_modules/engine.io-client/lib/transport.js.Transport.onPacket @ transport.js:149
push../node_modules/engine.io-client/lib/transport.js.Transport.onData @ transport.js:141
ws.onmessage @ websocket.js:160
有问题的代码部分如下:
const ControllerPage = () => {
const { loading, error, data, refetch } = useQuery(queries.GET_ALL_GAMES);
const [redirect, setRedirect] = useState(false);
useEffect(() => {
socket.on('redirect', (data) => {
if (data['target'] === 'controller') {
setRedirect(true);
}
});
socket.on('updateScoreboard', () => {
refetch();
});
}, [refetch]);
if (loading) return <div>Loading</div>;
if (error) throw error;
.... jada jada ...
render (
)
and so on
如您所见,我正在使用refetch方法在useQuery的定义中再次手动触发查询。因此,每次我输入throw(API调用throw / number / modifier)时,api都会在处理完throw之后返回socket.emit('updateScoreboard')
,然后记分板和控制器将获取最新数据以反映更改。
但是从错误中可以看到,离开一侧一次并返回该错误之后,refetch方法将不存在。如何防止此错误。
当我等待一小段时间后,在浏览器窗口的两个地址栏中输入内容,然后重新加载网站,它将再次正常运行并可以正常工作。但是,由于此系统应该在以后的信息亭模式下运行,因此刷新页面并不是一个好的解决方案。
任何指导将不胜感激
@ luke-dunscombe完全正确。
updateScoreboard必须清理。选择return () => socket.disconnect
作为清理方法将不起作用,因为套接字将停止正常工作,但是对此进行了更改:
const ControllerPage = () => {
const { loading, error, data, refetch } = useQuery(queries.GET_ALL_GAMES);
const [redirect, setRedirect] = useState(false);
useEffect(() => {
socket.on('redirect', (data) => {
if (data['target'] === 'controller') {
setRedirect(true);
}
});
socket.on('updateScoreboard', () => {
refetch();
});
return () => socket.off('updateScoreboard');
}, [refetch]);
if (loading) return <div>Loading</div>;
if (error) throw error;
从useEffect挂钩返回时,我通过停止收听效果很好的 updateScoreboard 事件来进行清理。
再次感谢@ luke-dunscombe寻求正确的提示和资源。