Implementing Server Sent Events in ReactJS

Helena Natanael
Tokopedia Engineering
4 min readOct 5, 2020

Have you ever heard about Server Sent Events (SSE)? I first tried it when I was assigned to work on a project which required files processing in Tokopedia. After looking at the few first pages on Google to learn more about SSE, I realize that it’s the most suitable way to cater to Tokopedia users’ needs.

This article explains how to implement SSE using JavaScript in the Front-End. To have a fully working SSE, you will need to setup the Back-End that can be read in this article.

Case Overview

In the project that I work on, users need to upload an Excel File containing the list of products that they want to upload in bulk. As the Excel File size might be large and the internet speed of each user may vary, we would like to make the experience of uploading big files as pleasant as possible. Therefore, we have decided to create a realtime progress bar to let the users know the number of products uploaded in the system. We are using SSE as a unidirectional way via HTTP to communicate from Server to Client, to get streams of data updates without hitting endpoints repeatedly in the progress bar.

Communication flow between Server and Client using Server Sent Events. (Image Source: PubNub)

How to implement it?

First, initialize the EventSource in your component. You’ll need the Backend endpoint that will be used. In my case, I also add withCredentials parameter so the EventSource also carries the cookies and user session.

const sse = new EventSource('[SSE_URL]', { withCredentials: true });

Event Source has some handlers: onerror, onmessage, and onopen. You can read more about it on the MDN website. In our use case, we only use onerror and onmessage.

The onerror handler is used to validate or log what causes error, then closes the connection using sse.onclose() method to prevent more errors and guide user to do actions that needed, e.g. retry to upload.

sse.onerror = () => {
// error log here
// after logging, close the connection
sse.close();
}

The onmessage handler is the heart of SSE usage. We can read the streams from Backend via this handler. As this handler needs some validations when reading and parsing data, I use a separate function to process the data I get and put it in the component’s state so I can render it or use it further in other functions.

function getRealtimeData(data) {
// process the data here
// pass it to state to be rendered
}
sse.onmessage = e => getRealtimeData(JSON.parse(e.data));

Last but not the least, don’t forget to invoke sse.close() for cleaning up the connection to Backend in your component to prevent memory leaks.

Here’s the complete code:

useEffect(() => {  const sse = new EventSource('[YOUR_SSE_ENDPOINT_URL]',
{ withCredentials: true });
function getRealtimeData(data) {
// process the data here,
// then pass it to state to be rendered
}
sse.onmessage = e => getRealtimeData(JSON.parse(e.data)); sse.onerror = () => {
// error log here

sse.close();
}
return () => {
sse.close();
};
}, [YOUR_DEPENDENCIES_HERE]);

Bonus: Here’s a preview of the progress bar that I implement in the Bulk Add page using SSE; you are welcome to try it if you have a shop in Tokopedia. 😄

Besides the progress bar, SSE can also be implemented in notification counter, a chat app, or any other use case that might need a realtime update from the server. Hopefully, you find this article useful and practical to implement SSE in your React Apps!

--

--