Redux middleware and how to use it with WebSockets

0
54
Redux middleware and how to use it with WebSockets


Middleware is a great place to connect to WebSockets if you use Redux. This article explains what the Redux Middleware is and how to use it with WebSockets.

In this blog, we also talk a lot about various backend technologies such as Express. One of the concepts popular there is middleware. In redux, it serves a similar purpose. If you want to know more about Express, check out TypeScript Express tutorial #1. Middleware, routing, and controllers

Here, we use Redux Toolkit with TypeScript. To get the same starting template, run .

The idea behind Redux middleware

Middleware allows us to add logic between the moment the user dispatches the action and when it reaches the reducer. One of the most straightforward use-cases for the middleware is logging.

Something that might be a bit confusing is that in Redux, middleware uses currying. It is a technique that involves breaking down a function that takes multiple arguments into a chain of functions that take only one argument each. Dan Abramov justifies it by the fact that we might want to use the JavaScript closures to our advantage. While not everyone agrees with this design decision, it might not be worth creating a breaking change to fix it at this point.

To understand it, let’s create a simple example.

loggerMiddlewarre.tsx

We could write the above code in a shorter way, but let’s be very explicit for now.

When we add the above middleware to our store, it results in logging every action we dispatch.

Chaining middleware

The argument is the most crucial thing to understand in the above code. Since we can have multiple middlewares, the function invokes the next one in the chain. If there are no middlewares left, it dispatches the action.

If we wouldn’t call the function, the action wouldn’t be dispatched.

Let’s add another example from the official documentation to visualize it better.

crashMiddleware.tsx

In this article, we use the Redux Toolkit. It adds some middleware to our store out of the box. To add new middleware while retaining the default ones, we can use the function as the documentation suggests.

store.tsx

The comes bundleded with the template mentioned at the top of this article.

Thanks to the fact that we’ve added before the , it executes first.

If we wouldn’t call the function in the , the would never run and the action wouldn’t be dispatched.

Using WebSockets with middleware

In API with NestJS #26. Real-time chat with WebSockets, we’ve created a backend for a chat application using socket.io. We can see that there are a few events that can happen. Let’s create an enum that contains all of them:

Even though in this article we use socket.io, the could would be very similar with barebones WebSockets.

chatEvent.tsx

Establishing a connection

To establish a connection, we need to have the URL of our backend application. A good way to store it on the frontend is through the environment variables.

.env
react-app-env.d.ts

Let’s also define the basics of our slice with the basic actions.

chatSlice.tsx

The last part of establishing a connection is to create middleware. The API we’ve created in this article needs authentication through cookies. To handle it, we need the argument.

chatMiddleware.tsx

Calling the function is how we can check if the action matches the one defined in the slice.

Our application establishes a connection through WebSockets when the user dispatches the action.

Sending chat messages and receiving them

All of the messages from our backend have a particular data structure. So let’s create an interface that matches it.

chatMessage.tsx

Now that we have the above interface, we can use it in our slice.

chatSlice.tsx

The last part of sending and receiving messages is to listen to all of the events and dispatch them.

chatMiddleware.tsx

In the above code, we do the following:

  • Emit the event as soon as the application establishes the connection.
  • Listen to the event that the backend emits in response to the event.
  • Emit the event when the user dispatches the action.
  • Listen to the event the backend emits when any of the users send a message.

Summary

In this article, we’ve explained what the middleware is in the context of Redux. When doing that, we’ve used Redux Toolkit and TypeScript. Since a middleware exists for the whole lifetime of our application, it is a good place to connect to the WebSocket. A middleware also has access to the current state and can dispatch actions. It can react to incoming messages and emit them when the user dispatches an action.



Source link

Leave a reply

Please enter your comment!
Please enter your name here