ContextAPI:如何在React中的上下文之间共享数据?

问题描述 投票:0回答:1

这是我的问题:

我的网站的验证位为“完整”。注册/登录后,用户会收到一个包含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;
javascript reactjs socket.io react-context
1个回答
0
投票

您需要将东西嵌套到使用用户数据上下文的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";
const socket = io(address);

export function getSocket() {
  return socket;
}

import { getSocket } from './socket-things';

const MyComponent = () => (
  <button onClick={() => getSocket().send('foo')} />
);
© www.soinside.com 2019 - 2024. All rights reserved.