我正在尝试在我的 React 应用程序中实现实时聊天。这是我第一次使用 socket.io,我遇到了一些麻烦。
我在 App.js
中创建了一个新的套接字和连接,如下所示:
const [socket, setSocket] = useState(null);
const setupSocket = () => {
const token = localStorage.getItem("token");
if(token != null && !socket) {
const newSocket = io("http://localhost:5000", {
query: {
token: localStorage.getItem("token"),
},
transport : ['websocket']
});
newSocket.on("disconnect", () => {
setSocket(null);
setTimeout(setupSocket, 3000);
});
newSocket.on("connect", () => {
});
setSocket(newSocket);
}
}
// set the socket whenever the App component loads
useEffect(() => {
setupSocket();
}, []);
并将其从 App.js
传递给其他组件,如下所示:
return (
<BrowserRouter>
<Navbar />
<Switch>
<Route exact path="/register" component={Register} />
<Route path="/login"
render={() => <Login setupSocket={setupSocket}/>}
exact
/>
<Route path='/chatroom'
render={() => <Chatroom socket={socket} />}
exact
/>
<Route path='/chat/:id'
render={() => <Chat socket={socket}/>}
exact
/>
</Switch>
</BrowserRouter>
);
我正在通过链接从 Chat
输入 Chatroom.js
组件:
<Button href={"/chat/" + String(chatroom._id)} className={classes.button} variant="contained" color="primary"> Join </Button>
当我尝试访问 Chat.js
中的套接字时,socket
为 null
:
import React, { useEffect, useState, useRef } from 'react'
import {withRouter, useLocation} from "react-router-dom";
const Chat = ({match, socket}) => {
const chatroomId = match.params.id;
useEffect(() => {
console.log("Chat ID: ", chatroomId);
console.log("Socket: ", socket);
socket.emit("joinRoom", {
chatroomId,
});
return () => {
socket.emit("leaveRoom", {
chatroomId,
})
}
}, []);
return (
<div >
CHAT
</div>
);
}
export default Chat;
你知道我做错了什么吗?我试图通过来自 socket
的行与 Chatroom.js
一起传递 chatroom._id
,但了解到以这种方式传递对象是不可能的。我将不胜感激!
答案 0 :(得分:0)
为什么不用context api在各个组件之间共享socket,而不是传入router?
上下文文件
import React, { createContext } from 'react';
import { io, Socket } from 'socket.io-client';
const socket = io('http://localhost:3000'),
SocketContext = createContext<Socket>(socket);
socket.on('connect', () => console.log('connected to socket'));
const SocketProvider = ({ children }: any) => {
return (
<SocketContext.Provider value={socket}>{children}</SocketContext.Provider>
);
};
export { SocketContext, SocketProvider };
然后在 App.jsx 中,像这样
import { SocketProvider } from './context/socket';
//
return {
<SocketProvider>
// other components
</SocketProvider>
}
之后,您可以在任何具有 useContext 钩子的子组件中使用套接字,如下所示 -
import React, { useContext, useEffect } from 'react';
import { SocketContext } from '../context/socket';
const Sample = () => {
const socket = useContext(SocketContext);