Javascript ContextAPI:如何在React中的上下文之间共享数据?
我的问题是: 我的网站的认证位是“完整的”。注册/登录后,用户将收到一个包含jwt令牌的cookie。接收到UserDataContext后,将向其提供用户的用户ID(uid)和用户名。uid用于服务器上的所有事情 io将用于通知后端从前端执行操作。套接字可用于通过react上下文对组件进行反应。我有两个上下文,UserDataContext和SocketContext。我需要跟踪哪个插座连接到哪个用户 我想我将在服务器上创建一个SocketManager类,它侦听新的套接字连接并通过uid将它们与用户关联。我试着用套接字的id来做这件事,但问题是id在重定向/刷新时会改变。因此,我需要一种通过套接字连接事件发送uid的方法。uid保存在UserDataContext中 如何将uid从UserDataContext获取到SocketContext?我应该合并这些上下文吗?这是正确的方向吗 App.js-Javascript ContextAPI:如何在React中的上下文之间共享数据?,javascript,reactjs,socket.io,react-context,Javascript,Reactjs,Socket.io,React Context,我的问题是: 我的网站的认证位是“完整的”。注册/登录后,用户将收到一个包含jwt令牌的cookie。接收到UserDataContext后,将向其提供用户的用户ID(uid)和用户名。uid用于服务器上的所有事情 io将用于通知后端从前端执行操作。套接字可用于通过react上下文对组件进行反应。我有两个上下文,UserDataContext和SocketContext。我需要跟踪哪个插座连接到哪个用户 我想我将在服务器上创建一个SocketManager类,它侦听新的套接字连接并通过uid将它
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;
import React,{Component}来自'React';
从“react Router dom”导入{BrowserRouter as Router,Switch,Route,Link};
从“./contexts/UserDataContext.js”导入UserDataContextProvider;
从“./contexts/SocketContext.js”导入SocketContextProvider;
从“./pages/Landing.js”导入登录;
从“/pages/components/global/Topnav.js”导入Topnav;
从“./pages/components/consoles/UserDashboard.js”导入UserDashboard;
导入“/Global.css”;
const App=props=>(
);
导出默认应用程序;
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;
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;
import React,{Component,createContext}来自'React';
export const UserDataContext=createContext();
类UserDataContextProvider扩展组件{
状态={
作者:错,
uid:错,
用户名:false
};
setUserData=data=>{
this.setState({uid:data.uid,username:data.tag})
}
render(){
返回(
{this.props.children}
);
}
}
导出默认UserDataContextProvider;
SocketContext.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;
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;
import React,{Component,createContext}来自'React';
export const SocketContext=createContext();
从“socket.io客户端”导入io;
const prod=(process.env.NODE_env==“production”);
const address=prod?window.location.hostname:“http://localhost:8080";
常量套接字=io(地址);
类SocketContextProvider扩展组件{
render(){
返回(
{this.props.children}
);
}
}
导出默认SocketContextProvider;
您需要使用用户数据上下文(或合并两个提供程序)将内容嵌套到SocketContextProvider。然后你可以:
- 发送一条特殊消息,在新uid更改时通知服务器,或
- 在您发送的每封邮件中发送uid
import io from 'socket.io-client';
const prod = (process.env.NODE_ENV === "production");
const address = prod ? window.location.hostname : "http://localhost:8080";
let socket = null;
export function getSocket() {
if(socket === null) {
socket = io(address);
}
return socket;
}
及
从“/socket things”导入{getSocket};
常量MyComponent=()=>(
getSocket().send('foo')}/>
);
我想我在一个教程中看到了它与上下文一起使用,并使用了它。这是一个更好的主意。当你说这不是一个“大罪”时,你是在暗示这是一个较小的罪,并且有更好的方法来做到这一点吗?拥有全球国家使得孤立地测试事情变得更加困难。这就是说,这也是可以测试的,因为你可以添加一些机制来用合适的东西替换socket
对象。Ps:我编辑了一些东西来创建和连接socket,只是在第一次真正需要的时候。如果你使用服务器端渲染,人们会共享socket…@quirimmo,不,web浏览器中的客户端无法与服务器上的同一套接字对象交互。在OP的用例中,看起来所有套接字交互都是经过身份验证的。