We often use the Redux technology in our work. Not everyone is familiar with it. And some people don’t even know what it is about. Well, I'll try to explain to you shortly what it is and why it is so interesting to us.

A pleasant surprise awaits those who read until the end of the article! Interested? Let’s go then!

Redux became the de facto standard as a data management technology for ReactJS applications. It is a convenient and easy method of structuring data in an application and displaying it on the client. Yet we hit a certain problem here. There is no place for side effects in the Redux scheme of work. As in the context of this article, only network requests are seen as side effects. Middleware can solve this problem.

Can Redux offer its own solution?

Two of the most common ways of dealing with side effects in Redux apps today are thunks and sagas.

Most people will ask, what are thunks and sagas? And how can they help?

The majority of projects use Redux Thunk to organize side effects. In principle, it gives a good result: it’s easy to read and test the code (but you still need to mock network requests). But it all is fair as far as the logic of your action creators (or thunks) is simple. Unfortunately, for more than a few functions the code becomes harder to read, which makes it even more difficult to test.

In this situation, Redux Saga comes to the rescue. Redux Saga is an alternative approach to the organization of side effects. Instead of dispatching functions processed by Redux Thunk you create saga and write all the logic of event stream processing. Unlike thunks that are carried out when you dispatch them, sagas run in the background right after the app is launched. Sagas observe all actions that the store dispatches and decide what to do with them.

At this point, we can allocate three key benefits of sagas:

  • Simplicity in organizing difficult side effects sequences
  • Declarative style
  • Simplicity of testing

So how can the saga be put into practice?

Let’s review an example of a simple saga which sends a network request.

function* request(action) {
   const response = yield call(api.method, action.payload)
   if (response.token) {
     yield put({type: ‘API_CALL_SUCCESS’, payload: response.token});
   } else {
     yield put({type: ‘API_CALL_FAIL’})
   }
}

function* mySaga() {
   takeEvery(‘API_CALL’, request)
}

Everything is quite simple and clear here. Our saga (which is the generator) expects some action, and after receiving it runs the handler function.

Is it possible to simplify the code more? Of course!

To make this code clearer and simpler, it is enough to improve it a little bit:

function* mySaga() {
   while ( true ) {
   yield take(‘API_CALL’);
   const response = yield call(api.method, action.payload)
   if (response.token) {
     yield put({type: ‘API_CALL_SUCCESS’, payload: response.token});
   } else {
     yield put({type: ‘API_CALL_FAIL’})
   }
}

In this example, we have launched an endless loop in this saga. As a result, the saga stops at the instructions “yield take ( ‘API_CALL’)” and waits for the desired action.

Special functions (effects) control sagas. In fact, these functions simply give a description of the desired call. For example, the call effect returns an object with reference to the desired function or a generator with parameters that it needs to be called with.

Since all calls in the saga are indirect (through effects), it’s easy to test them.

We can test our saga in this way:

if(‘should handle API_CALL type and perform api.method’, () => {
   const saga = mySaga();
   let next = saga.next();
   expect(next.value).toEqual(take(‘API_CALL’}));
   next = saga.next({type: ‘API_CALL’, payload: 1});
   expect(next.value).toEqual(call(api.method, {payload: 1}));
   next = saga.next({token: 1});
   expect(next.value).toEqual(put({type: ‘API_CALL_SUCCESS’}, payload: 1}))
});

Thus, Redux Saga allows you to write a complex sequence of synchronous and asynchronous events in a clear and declarative style without callbacks.

Well, in the end, I would like to share a useful link with you. It’s for those who are not left indifferent to the info above and who want to understand this topic in more detail here.

What is Redux Saga? Exploring the Middleware for Managing Side Effects in Redux

Redux Saga is a middleware React library that simplifies side effects management in Redux. These side effects can include data fetching from an API, accessing the browser cache, or making asynchronous calls. Redux Saga actions make these operations easier to manage and test.

It helps to keep total control over your code by providing different approaches to parallel execution, task concurrency, task racing, etc. The main features of Redux Saga include:

  • Sagas: Sagas are functions that control the flow of async operations. They track certain actions and perform them.
  • Middleware: Redux Saga is a middleware in your Redux store that captures the action before it reacts to the reducers.
  • Generators: Generators is a JavaScript function for asynchronous workflow processing. Sagas yield plain objects, so there is no need to launch asynchronous operations, which makes testing easier and more effective. 

Understanding the yield put Command in Redux Saga

In Redux Saga, the yield put command is responsible for dispatching the action to the Redux store. This action can trigger side effects or update the state of current actions. Yield put command makes the saga out the execution on pause and wait until the action is dispatched. It gives more predictability to the sequence of Redux saga actions and side effects.

The yield put effect takes an object as an argument, where a type property specifies any data and action type that has to be included in the action's payload. Let’s see an example:

Why You Should Use Redux Saga - photo 2

As you can see in the example above, the put effect dispatches the FETCH_USERS_SUCCESS action with the user data returned from the API call.

Yield call and yield are not the only effects in redux-saga. Other effects, such as yield take, yield fork, and yield race, which you can use depending on your requirements.

Conclusion

In this article, our goal was to introduce you to another technology that we use in our work.

Now you know the main benefits of sagas in Redux. Thus, you see the bigger picture!

Moreover, you know how to create and test a saga. Feel free to use the code!