React & Redux + Sagas: What, How, Why

DISCLAIMER: As you may know as a programmer there are many ways to achieve the same thing and there are a great number of ideas and philosophies about how to code and organize a project, especially when it comes to new and emerging technologies;therefore this article is written (obviously) from my perspective as a programmer and is biased accordingly to my own ideas about how to code.

In this article I assume you are already familiar with JavaScript and familiar at building front end web applications, perhaps even a little familiar with React and the main purpose of what you are about to read is to share my understanding and experience about this concepts and tools and how I came to make the most of them.

This is not an article specifically about how to use react, redux or sagas but is proposed as a possible explanation of how to use them together, so I’m going to be presenting topics fast (and furious) as I try to explain everything.

(it’s also my first article)

What is React?

A JavaScript library for building user interfaces.

What is Redux?

A predictable state container for JavaScript apps.

What are Sagas?

A library that aims to make side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) in React/Redux applications easier and better.

How are things related?

if you are already familiar with react & redux you may skip the following

While React let’s create UI by making simple and complex components that is just UI and almost any application has some logic behind it, and one big part of that logic is your application state, which refers to all the data that interacts across your pages.

Example: If you are building an E-Shop or E-Commerce app, your application state will be composed of products, categories, tags, discounts, user information, etc.

As your application grows your application state will grow with it and it will become harder and harder to manage; here is where Redux comes into play, redux allows you to separate your application state in one place (called Store) and go from one state to the next state using actions, read more about it here. By doing this you can manage your state logic independently from your UI and let the UI change as the state changes.

I’m not certain but I think that is why it’s called React, because it REACTS to the changes in the app state …

Here of course there is one problem, because you are building a web app, in your logic you are bound to make some Asynchronous code which can mess up the flow of your actions a bit or a lot, one way of sort of “fix” it is to use thunk, which I did at first but I didn’t like complicating my redux actions so much, as I like to keep my actions as simple as possible. Here is where Sagas saves the day, sagas allow you to decouple all the Asynchronous logic from your regular actions and do some pretty wild/weird stuff taking advantage of the new JavaScript specifications, you can read more about it here.

How and Why I do things this way?

If you reach this part and can’t make anything of this I recommend you read all about React, Redux and Sagas from the links above, give it a good spin, make your own thoughts and then come back here because this is the part where I explain HOW I manage to use all of this in a effective way AFAIK.

A bit of “narrative”

You’ve started with React, it’s new, it’s cool, making components is great but how do your pages communicate? do you make services, singletons? is your data flowing all over the place? … all of the sudden you encounter Redux and it’s great and perfect, now your data (app state) is all one place organized in reducers and your actions “mutate” the state in a fun and predictable way, but wait! Some of your actions are getting pretty messed up, there are too many async calls and logic to take care in the middle that involves many actions… Ok, not to dispair, you can use sagas to group the logic of the complex actions and flows aaannd you’re done! Everything is organized. UI reacts naturally to the state, actions represent what the app can do, reducers tells you how the state mutates and the sagas handle the logic and side effects …. But … you’ve just added A LOT of work and code to your project… and now every time you want to add something you have to write an action, write a reducer, maybe even write a saga or modify one, you have to wonder where do I put this? Does this belongs to this reducer? or it belongs to this other one? your actions names are getting conflicted. This reducer is so full that it no longer represents anything that make sense! …

Ok! … Ok …. Just Breath …

Maybe you never had this problem and you are awesome, but this was my experience, once I started using this new tools I ended up making things much more complicated, while cleaning some of my process I over-worked some code that should remained simple.

What did I learned?

The most important thing I discovered after this mess (that was suppose to clear things) was to use this tools when and where it made at least some sense. Sometimes you get over excited with a new tool or a new architecture and try to implement it everywhere, maybe to have some consistency or because you think it will grant benefits everywhere, but the reality is that IT REALLY helps in some cases and IT REALLY does not in some others.

Let’s break down everything:

Redux is great, but not all your logic and data belongs in the redux state, you probably have a few (or a lot) simple components that manage their own state with their own properties because their are not really needed elsewhere.

Sagas are great, but not all your logic needs to run in a saga, putting your logic and side effects inside a saga really helps when you want to make use of it in a lot of places, but if you have a page that needs a certain logic that is ONLY required in that particular page, maybe you don’t go through the trouble of writing a saga for it…. and actions … and reducers.

Putting things in perspective

How do I decide to put some of my state in the Redux Store?

When the data is gonna be needed in several places. If you have several components or pages that are require to access the same set of data you will benefit greatly from having it on the redux state. Take note that I said same set, which means exactly the same one.

Example: the products inside your cart shop in an e-commerce app, you are most likely to require that SAME cart along various pages, in contrast, data about products may be needed in several pages but every page may require a different set of products, with different filters, with different properties, etc etc. So if this pages require a different set they will perhaps be requiring a modified version of it, or a smaller or larger set and they will end up just making another call to the server to get the correct set, replacing the set in the app state;

If I have a particular page which need access to some piece of data that is not needed ANYWHERE else, then there is no need to write a whole lot of code for almost no benefit.

How I decide to put some of my logic/side-effects in a Saga?

Same answer. When that logic is going to be needed in several places, sagas are a very good way to enforce the DRY principle, because you can isolate your code and then it’s easier to modify and test. But if your code is only in one place by putting it in a saga you simply move the code and could add some complexity.

What are the benefits of implementing everything everywhere?

Consistency: if you have everything in actions, reducers and sagas, there is only one place to look when you have to maintain your logic, if you have a large team this could be a great benefit.

Testing: testing is made homogeneous, you can make unit tests for every action to check if their alter the app state correctly and have certainty that there are no excluded features.

Purism: if you are used to follow principles to the letter, this will effectively keep every aspect of your project separated and isolated so maybe team members that know little about React can only work on the logic and others that know little about Redux/Sagas can work on the components.

What are the drawbacks of implementing everything everywhere?

Larger code base: having to write actions, reducers and sagas for everything will increase the amount of code significantly.

Time consuming: this is an obvious one but larger code base means more time writing code.

More analysis: figuring out what goes where and how should you combine everything together could bring you to a halt and prevent you from actually coding what you need to code.

Conclusion

I figured out that if your project is well organized and your components themselves are independent and predictable you can easily get away with just partially implementing this tools and not only you will get more done in less time, it will also be less stressful to analyze your logic and your components specially when you are really close to a deadline and you just need to make things work, and as I said if you are building well enough components and your logic is not mixed up in a weird way, maintaining the project is actually easier, is much more easy to refactor some logic inside a single component and put it in the redux state than having to write an awful lot of code and gain no real benefit from it.

I’m gonna leave it quote here that I red when I was having trouble deciding why and how to do things, I honestly don’t remember where it was (somewhere in the github community) but it really helped me to implement all this tools. So whenever you don’t where to put something or how to implement it … remember:

“do whatever feels less awkward”
Show your support

Clapping shows how much you appreciated Gabriel Matusevich’s story.