useContext value of an initalized socket.io-client object always returns null object

37 views Asked by At

I don't get what I am doing wrong here.

Even after extensively googleing the issue I still cant see the problem.

I try to wrap a websocket into a context such that I can access it anywhere in my react application.

I think my setup is pretty basic:

WebSocketContext.js:

import React, { createContext, useContext} from 'react';
import io from 'socket.io-client';

const WebSocketContext = createContext(null);

export const useWebSocket = () => {
    return useContext(WebSocketContext);
};

export const WebSocketProvider = ({ children }) => {
    const ws_url = "ws://localhost:5000"
    const socket = io(ws_url)
    console.log("WebSocketProvider socket: " + socket)

    return (
        <WebSocketContext.Provider value={socket}>
            {children}
        </WebSocketContext.Provider>
    );
};

And this is how I use it in my App.js:

import { useEffect } from "react";
import WSMessageComponent from "./WSMessageComponent";
import { WebSocketProvider, useWebSocket } from "./WebSocketContext";
import io from 'socket.io-client';

const App = () => {   
    let socket = useWebSocket()
    console.log("App.js: socket:" + socket)

    useEffect( () => {
        console.log("App.js: useEffect socket:" + socket)
        // when uncommenting the next line it works. Which means it basically works.
        //socket = io("ws://localhost:5000") 
        if(socket) {
            socket.on("ping", (msg) => {
                console.log("Msg from server: " + msg)
            })
            return () => { socket.off("ping") /* Unsubsribe from event PING falls die Komponente gelöscht wird */}
        } else {
            console.log("if(socket) == false")
        }
    }, [socket])

    return (
        <WebSocketProvider>
            <WSMessageComponent/>
        </WebSocketProvider>
    );
}

export default App;

On my server I am sending broadcast messages via Flask-SocketIO.

As mentioned in the code if I uncomment socket = io("ws://localhost:5000") i do receive the broadcast messages from the server.

Even if I modify the above provider as in the following the problem remains the same:

export const WebSocketProvider = ({ children }) => {
    const [socket, setSocket] = useState(null)
    useEffect( () => {
        setSocket(io("ws://localhost:5000"))
        console.log("WebSocketProvider socket: " + socket)
    }, [])

    return (
        <WebSocketContext.Provider value={socket}>
            {children}
        </WebSocketContext.Provider>
    );
};

But if I use the context solution I get the following output in the console:

App.js: socket:null
installHook.js:1 App.js: socket:null
WebSocketContext.js:13 WebSocketProvider socket: [object Object]
installHook.js:1 WebSocketProvider socket: [object Object]
App.js:13 App.js: useEffect socket:null
App.js:22 if(socket) == false
App.js:13 App.js: useEffect socket:null
App.js:22 if(socket) == false

Can anybody tell me what I am doing wrong here? Thanks :)

0

There are 0 answers