我正在使用react hook来创建应用程序,并使用socket.io-client用于flask和react之间的通信,尝试访问应用程序的不同组件中的socket.io-client实例,
请检查socket-Instance.js内的以下代码,连接后创建了socketio实例并使用dispatch存储在store.js中,
在 device.js 中,尝试访问存储的套接字实例,并在切换时发出数据,
但是在套接字实例中,我试图打印 console.log(socketInstance);
这是 null
我想创建一次套接字实例,并尝试使用连接的套接字从不同的组件发出数据
使用 https://www.npmjs.com/package/socket.io-client这个库
索引.js
import { StateProvider } from './shared/store';
const app = (
<StateProvider>
<AppRouting />
<SocketInstance />
</StateProvider>
);
store.js
import React, { createContext, useReducer } from 'react';
const initialState = {
deviceStatus: []
};
const store = createContext(initialState);
const { Provider } = store;
const StateProvider = ({ children }) => {
const [state, dispatch] = useReducer((currentState, action) => {
const newState = { ...currentState };
console.log(action.type);
switch (action.type) {
case 'socket':
newState.websocket = action.currentState
return newState
default:
throw new Error();
};
}, initialState);
return <Provider value={{ state, dispatch }}>{children}</Provider>;
};
export { store, StateProvider }
socket-instance.js
mport React, { useEffect, useContext, useState } from 'react';
import { store } from '../shared/store';
import socketio from 'socket.io-client';
const ENDPOINT = "http://localhost:5000/";
function SocketInstance() {
const { dispatch } = useContext(store);
const [socketInstance, setSocket] = useState(null);
useEffect(() => {
const currentSocket = socketio.connect(ENDPOINT, {
reconnection: true
})
currentSocket.on('connect', function (msg) {
console.log("Server connected...");
});
currentSocket.on("disconnect", function () {
console.log("server disconnected from client");
});
setSocket(currentSocket)
console.log("=======set socket instance==========");
console.log(socketInstance);
dispatch({ type: 'socket', socket: socketInstance })
}, [])
return (
<div >
</div>
)
}
export default SocketInstance;
device.js
function DeviceStatus() {
const { state, dispatch } = useContext(store);
const { deviceStatus, websocket } = state; //deviceCommand should be same as setting new state in store
const [isEnable, setIsEnabled] = useState(false)
const toggleSwitch = (checked) => {
setIsEnabled(checked)
dispatch({
type: "updateDeviceStatus",
deviceId: 21,
deviceState: checked,
})
console.log("******before emit***************");
console.log(deviceStatus);
console.log("******check websocket ***************");
console.log(websocket);
if (websocket) {
console.log("websocket instance can accessible");
// websocket.emit("datafromui", deviceStatusFromUI)
}
}
return (
<div className="devicestatus-item" >
<span>{DeviceStatusConst.FRONT_LL}</span>
<Switch checked={isEnable} onChange={toggleSwitch} />
</div>
)
}
export default DeviceStatus
非常感谢您的帮助,“提前致谢”
最佳答案
SocketInstance 的 useEffect 有一个空的依赖数组,这意味着它只会在第一次渲染后运行一次。它记录 null,因为状态在下一次渲染之前不会更新。
就跨组件使用相同的实例而言,您可以简单地在组件外部定义 currentSocket(或在单独的文件中并将其导出)并将其作为 props 向下传递。更好的是,您可以使用上下文来代替。另外,我建议在 SocketInstance 组件卸载时清理事件监听器。
CreateContext.js
import React from 'react'
import socketio from 'socket.io-client'
export const socket = socketio('http://localhost:5000/')
const SocketContext = React.createContext(socket)
export const SocketProvider = SocketContext.Provider
export const SocketConsumer = SocketContext.Consumer
export default SocketContext
Index.js
import { StateProvider } from './shared/store'
import { SocketProvider } from './shared/context/SocketContext'
const app = (
<StateProvider>
<SocketProvider>
<AppRouting />
<SocketInstance />
</SocketProvider>
</StateProvider>
)
socket-instance.js
import React from 'react'
import SocketContext from './shared/context/SocketContext'
const SocketInstance = () => {
const currentSocket = React.useContext(SocketContext)
React.useEffect(() => {
console.log(currentSocket)
const listener = message => {
console.log(message)
}
currentSocket.on('some-event', listener)
return () => currentSocket.off('some-event', listener)
}, [])
return (
<div></div>
)
}
关于reactjs - 如何存储 socket-io-client 实例以通过应用程序访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64482843/