在 React 组件之间传递 Socket.io 对象

时间:2021-04-26 16:21:45

标签: reactjs sockets socket.io

我正在尝试在我的 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 中的套接字时,socketnull

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,但了解到以这种方式传递对象是不可能的。我将不胜感激!

1 个答案:

答案 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);
相关问题