useEffect 中的套接字连接事件在创建组件时不起作用,但在 React 中刷新页面后起作用
Posted
技术标签:
【中文标题】useEffect 中的套接字连接事件在创建组件时不起作用,但在 React 中刷新页面后起作用【英文标题】:socket connect event inside useEffect does not work when component is created but works after refreshing the page in React 【发布时间】:2022-01-05 14:37:38 【问题描述】:我想将一个套接字实例传递给我的所有反应组件,因此我在 App.js 的 useEffect 内连接一个套接字,该套接字包含所有组件,并将我的侦听器保持在导航栏组件的 useEffect 内。 首次打开应用程序时,useEffect 被触发,但套接字未连接。但是当我刷新页面时,套接字被连接并被轻松传递给我想要的组件。
App.js
function App()
const authCtx = useContext(AuthContext)
const username = authCtx.username
const [socket, setSocket] = useState(null);
const [user, setUser] = useState("");
useEffect(() =>
setSocket(io("http://localhost:7000"));
, []);
useEffect(() =>
socket?.emit("join_room",
chatroom:username
);
, [socket, user]);
return (
<div>
authCtx.isLoggedIn && socket && <MainNavigation socket=socket />
authCtx.isLoggedIn && <FloatingBtn/>
<Switch>
authCtx.isLoggedIn && socket && <Route exact path='/Chat'>
<Chat socket=socket />
</Route>
</Switch>
</div>
);
export default App;
【问题讨论】:
【参考方案1】:请注意,在 useEffect 中,依赖项是 authContext.username,而不是用户。
useEffect(() =>
if(authCtx.username && socket)
socket?.emit("join_room",
chatroom: authCtx.username
);
, [socket, authCtx.username]);
要拥有一个全局套接字实例,您可以创建一个 SocketContext,如下所示:
import createContext, useContext from "react";
const SocketContext = createContext(
socket: undefined
);
export const SocketProvider = ( childern ) =>
const authCtx = useContext(AuthContext);
const [socket, setSocket] = useState(null);
useEffect(() =>
setSocket(io("http://localhost:7000"));
, []);
useEffect(() =>
if(authCtx.username && socket)
socket?.emit("join_room",
chatroom: authCtx.username
);
, [socket, authCtx.username]);
return (
<SocketContext.Provider value= socket >
childern
</SocketContext.Provider>
);
;
export default SocketContext;
在你的 index.js 中定义它:
import ReactDOM from "react-dom";
import SocketProvider from "../SocketContext";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<AuthProvider>
<SocketProvider>
<App />
</SocketProvider>
</AuthProvider>,
rootElement
);
并在每个组件中使用它,例如:
import React, useContext from "react";
import SocketContext from "../SocketContext";
const RandomComponent = () =>
const socket = useContext(SocketContext);
React.useEffect(() =>
console.log(socket);
, [socket]);
return <div></div>;
;
不将其作为道具传递。
【讨论】:
不知道如何感谢您。 :)以上是关于useEffect 中的套接字连接事件在创建组件时不起作用,但在 React 中刷新页面后起作用的主要内容,如果未能解决你的问题,请参考以下文章
在哪里使用 React 中的 Hooks 定义需要来自全局状态的数据的套接字事件侦听器
如何在 UseEffect 中将事件侦听器添加到 UseRefs