DEV Community

Cover image for Using WebSockets with React

Using WebSockets with React

Murat Can Yüksel on September 12, 2021

To learn more about programming, subscribe to my Youtube channel => https://www.youtube.com/channel/UCP1hJydcsPZCwbn8rPiohsg For my last proj...
Collapse
 
tzii profile image
Vu

I guess your code will create multiple instances of Websocket, you should put this in useEffect hook to avoid that

Collapse
 
vsalvans profile image
Víctor Salvans Montesó

That's right. I will even go further and create a hook ( useWebsocket that uses useEffect internally) where you can pass the callback functions onopen and onmessage and returns a send function for instance or whatever you need from the hook.

Collapse
 
muratcanyuksel profile image
Murat Can Yüksel

Hey man, I wrote a reply to Vu's comment. Feel free to join the discussion :)

Thread Thread
 
tzii profile image
Vu • Edited

Every time the client receives new message => setBids called => component rerender => create new instance of Websocket => create new connection (1 request in devtools). This's not good, right :)))
This is my idea. You can check more in network tab in devtools and see the differents.


const apiCall = {
    event: 'bts:subscribe',
    data: { channel: 'order_book_btcusd' },
};
function App() {
    const [bids, setBids] = useState([0]);

    useEffect(() => {
        const ws = new WebSocket('wss://ws.bitstamp.net');
        ws.onopen = (event) => {
            ws.send(JSON.stringify(apiCall));
        };
        ws.onmessage = function (event) {
            const json = JSON.parse(event.data);
            try {
                if ((json.event == 'data')) {
                    setBids(json.data.bids.slice(0, 5));
                }
            } catch (err) {
                console.log(err);
            }
        };
        //clean up function
        return () => ws.close();
    }, []);
    const firstBids = bids.map((item, index) => (
        <div key={index}>
            <p> {item}</p>
        </div>
    ));

    return <div>{firstBids}</div>;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
muratcanyuksel profile image
Murat Can Yüksel

Hello, I have 4 components that I repeat the same method and it seems like each one waits its turn to display the data. I was wondering how to fix that, I guess you're taling about that? In my original code, I have useEffect in this manner :

 useEffect(() => {
    ws.onmessage = function (event) {
      const json = JSON.parse(event.data);
      try {
        if ((json.event = "data")) {
          dispatch(getOrderBookData(json.data));
        }
      } catch (err) {
        console.log(err);
      }
    };
    //clean up function
    return () => ws.close();
  }, []);
Enter fullscreen mode Exit fullscreen mode

What should I do to overcome the problem you mentioned?

Collapse
 
mzrt profile image
Evgeniy Tortumashev

if ((json.event = "data")) {

Why "=", and not "==="?

Collapse
 
dcsan profile image
dc

Because he's not using a linter?
That's why he gets a lot of unfiltered events.

Collapse
 
muratcanyuksel profile image
Murat Can Yüksel • Edited

Good question, that was some snippet I found while trying to figure out how to get started, and itseemed to work. I didn't even think about it. Will it cause any problems? It didn't so far...

Collapse
 
mzrt profile image
Evgeniy Tortumashev

This condition will always be true because the assignment operator is used instead of the comparison operator.

Thread Thread
 
muratcanyuksel profile image
Murat Can Yüksel

Gonna edit it (y)

Collapse
 
mattcale profile image
Matthew Cale

Clear, concise and useful! Thanks for sharing. As others have mentioned using the useEffect hook is likely the best spot for initializing WS, but it adds additional code so 🤷‍♀️. In any case really great work

Collapse
 
ergisgjergji profile image
ergisgjergji

Sorry but this article has many technical errors.
Seems you've been aware about them yet you didn't correct the article.

Collapse
 
muratcanyuksel profile image
Murat Can Yüksel

True. I haven't touched websockets after writing this article though, worked on some other stuff and all. I'm thinking of trying to correct it as much as I can once I get the time to dive into websockets further.

Collapse
 
sandrinjoy profile image
Sandrin Joy

I agree

Collapse
 
codecustard profile image
Emmanuel Barroga

Why use websocket and not socket.io? Just asking to exchange some dialog between the two.

Collapse
 
muratcanyuksel profile image
Murat Can Yüksel

To be honest, I'm not even sure what's the other one. I had 3 days to learn websockets and redux, so I went with that way.

What's the difference between the two? Why should I check socket.io?

Collapse
 
vsalvans profile image
Víctor Salvans Montesó • Edited

Websocket is the native api from your browser whereas socket.io does not implent the same api although it can use websocket under the hood if the browser support it, besides it has the server version that helps the backend keep the same interface with the client and add extra features as authentication , etc.

Collapse
 
antonioallen77 profile image
AntonioAllen77

Once the WebSocket server is created, we had to accept the handshake on receiving the request . dua to make someone call you

Collapse
 
anjali1102 profile image
Anjali Chauhan

thank you so much !
helpful for my assignment