Skip to content Skip to sidebar Skip to footer

Websockets With Functional Components

I'm using websockets in my React application. The application is supposed to consist of function components only. Imagine the application consists of two 'tabs': one irrelevant, an

Solution 1:

As @skyboyer has written in a comment under your question, you could use useRef hook to hold WebSocket and it will be more correct since you are not going to change or recreate WebSocket object. So you don't need useState hook.

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. more

So you could change your code to:

constChat = () => {
    const [messages, setMessages] = useState([]);
    const webSocket = useRef(null);

    useEffect(() => {
        webSocket.current = newWebSocket("ws://url");
        webSocket.current.onmessage = (message) => {
            setMessages(prev => [...prev, message.data]);
        };
        return() => webSocket.current.close();
    }, []);
    return<p>{messages.join(" ")}</p>;
};

Solution 2:

probably a good option is to have in a separate WS instance for manage the WS operations and used it where you need it, for example.

classWebSocketClient {
    static instance = null;
    callbacks = {};

    staticgetInstance() {
        if (!WebSocketClient.instance) WebSocketClient.instance = newWebSocketClient();
        returnWebSocketClient.instance;
    }

    constructor() {
        this.socketRef = null;
    }

    addCallbacks = (...callbacks) =>this.callbacks = { ...callbacks };

    connect = () => {
        const path = 'YOUR_SOCKET_PATH';
        this.socketRef = newWebSocket(path);
        this.socketRef.onopen = () => {
            console.log('WebSocket open');
        };

        this.socketRef.onmessage = e => {
            this.socketNewMessage(e.data);
        };

        this.socketRef.onerror = e => {
            console.log(e.message);
        };

        this.socketRef.onclose = () => {
            console.log("WebSocket closed let's reopen");
            this.connect();
        };
    }

    state = () =>this.socketRef.readyState;

    waitForSocketConnection = (callback) => {
        const socket = this.socketRef;
        const recursion = this.waitForSocketConnection;
        setTimeout(
            () => {
                if (socket.readyState === 1) {
                    console.log("Connection is made")
                    if (callback != null) {
                        callback();
                    }
                    return;
                } else {
                    console.log("wait for connection...")
                    recursion(callback);
                }
            },
        1);
    }

}

exportdefaultWebSocketClient.getInstance();

So in your component will be.

importReact, { useEffect } from'react';
importWSCfrom'wsc';


constTest = ({}) => {

    useEffect(()=>{
        WSC.connect();
        WSC.waitForSocketConnection(()=>{
            'HERE_YOUR_CALLBACKS'
        });
    },[])
}

With this way always return the same instance.

Post a Comment for "Websockets With Functional Components"