这是我的问题:
我的网站的验证位为“完整”。注册/登录后,用户会收到一个包含jwt令牌的cookie。收到后,将为UserDataContext提供用户的用户ID(uid)和用户名。 uid用于服务器上的所有事物。
Socket.io将用于告诉后端从前端执行操作。套接字可用于通过反应上下文来反应组件。我有2个上下文,UserDataContext和SocketContext。我需要跟踪哪个套接字连接到哪个用户。
我想我将在服务器上创建一个SocketManager类,以侦听新的套接字连接,并通过uid将其与用户相关联。我尝试使用Socket的ID来执行此操作,但是问题是ID会在重定向/刷新时更改。因此,我需要一种通过套接字连接事件发送uid的方法。 uid保留在UserDataContext中。
如何将uid从UserDataContext获取到SocketContext?我应该合并这些上下文吗?这是正确的方向吗?
App.js-
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import UserDataContextProvider from './contexts/UserDataContext.js';
import SocketContextProvider from './contexts/SocketContext.js';
import Landing from './pages/Landing.js';
import Topnav from './pages/components/global/Topnav.js';
import UserDashboard from './pages/components/consoles/UserDashboard.js';
import './Global.css';
const App = props => (
<div>
<UserDataContextProvider>
<Topnav />
<SocketContextProvider>
<Switch>
<Route exact path='/' component={Landing} />
<Route exact path='/dashboard/:id' component={UserDashboard} />
</Switch>
</SocketContextProvider>
</UserDataContextProvider>
</div>
);
export default App;
UserDataContext.js-
import React, { Component, createContext } from 'react';
export const UserDataContext = createContext();
class UserDataContextProvider extends Component{
state = {
auth: false,
uid: false,
username: false
};
setUserData = data => {
this.setState({uid: data.uid, username: data.tag})
}
render(){
return (
<UserDataContext.Provider value={{state: this.state, setUserData: this.setUserData}}>
{this.props.children}
</UserDataContext.Provider>
);
}
}
export default UserDataContextProvider;
SocketContext.js-
import React, { Component, createContext } from 'react';
export const SocketContext = createContext();
import io from 'socket.io-client';
const prod = (process.env.NODE_ENV === "production");
const address = prod ? window.location.hostname : "http://localhost:8080";
const socket = io(address);
class SocketContextProvider extends Component{
render(){
return (
<SocketContext.Provider value={{socket:socket}}>
{this.props.children}
</SocketContext.Provider>
);
}
}
export default SocketContextProvider;
您需要将东西嵌套到使用用户数据上下文的SocketContextProvider中(或合并这两个提供者)。然后,您可以:
也就是说,使用上下文和提供程序在传播状态更改(例如用户名,主题,诸如此类)方面非常有用,而在传播诸如套接字之类的“活动对象”时则很少。
对于您的情况,因为您已经有了套接字的模块级全局,所以仅放弃套接字的提供者和上下文并不是一个大罪过,并且简单地
import io from 'socket.io-client';
const prod = (process.env.NODE_ENV === "production");
const address = prod ? window.location.hostname : "http://localhost:8080";
const socket = io(address);
export function getSocket() {
return socket;
}
和
import { getSocket } from './socket-things';
const MyComponent = () => (
<button onClick={() => getSocket().send('foo')} />
);