Redux Core Principles Explained

Angga Dwi Arifandi
The Startup
Published in
9 min readNov 7, 2019

I started learning about Redux when my day to day job requires me to learn the principles. It took me a while to really understand the concept behind it, and there’s still many things i haven’t really get a grasp on Redux especially on the advanced side. So after i think i got the grasp of its core principle, i think i could write and share my understandings of it here. I’ll try to explain with simple terms and analogies, so hopefully you too can understand the core principles of it. So here it is.

State management is one of the hot topics of UI Development, which includes Front End Development, Mobile Apps Development, etc. I think why its really interesting to talk about is because, its tricky but its very important. Made one mistake, and boom! your project’s life is on edge. This happens because as your project scope goes bigger and bigger, there are more and more data it holds.

Unfortunately for us developers, those data ain’t gonna save itself. We need to manage them as good as we can because its needed by our component here and there, back and forth. Imagine that you’re building an e-commerce application, that holds 1000 data at any given time and you need the customer’s email address at 5 components on one screen, and you need them again for other 3 components on other screen. And you didn’t manage your state properly on that app so the data was everywhere, on different files, different folders here and there, then you’re officially screwed.

That’s why we need to give our all to find suitable state management that fits our projects.

There are a lot of state management options for us to pick, whatever technology we use on our project. And one of them is Redux. I’ll try to give you a little bit context of what redux is, and why is it good concept to manage state, before explaining the core concepts.

Originally, Redux is a JavaScript library to manage application state. It really grows its popularity among React developers every now and then. Redux first introduced to the public on React Europe 2015 by Dan Abramov in a talk about React Hot Reloading with Time Travel. Redux is created by Dan Abramov and Andrew Clark, both were React core team at Facebook.

Dan Abramov’s talk about React Hot Reloading with Time Travel

If you watch Dan’s talk about Time Travel, you can see that the original motivation of redux’s creation is that he wants to create a developer tools that’ll enable us to go back and forth through an application state so that we can debug when exactly the app’s behavior went south. And after that, it grows popularity so much around React community and even non-React developers.

Right now, Redux already had some ported version of it in various language. Some of it are Kotlin, Swift, and Dart. Which are the language that builds popular apps on Android and iOS. Having used redux in my day to day job myself, i think why Redux is so popular is because it’s maintainable, testable, and there’s a lot of resources out there on how to use them. And most importantly, the community really backed the development on Redux itself, so we have some kind of “safety net”.

And why do i think redux is a good state management? First, i already tried several state management concepts for UI development here and there. Some of them offers bidirectional data flow, while Redux aren’t, not that its not good but i think i’m more suited to the unidirectional data flow like the one Redux has because it makes the scenario of an application more predictable. And, my experience in unit testing with redux was so good because the way redux separate the action and the reducers made it so easy to test the logic.

Unidirectional Data Flow of Redux

Alright let’s cut to the chase. So redux was inspired by Facebook’s Flux architecture, with some modifications in such way so time travel would be possible. Redux’s core operation is similar to functional’s programming Reducer function, or often called by the name Fold. How does it really work? and i think the magic lies here. So imagine that you’re making an origami from a single paper. And you want to make a shuriken origami like one below.

You see that there are two ways to do it, first one is we cut the paper to make one side of the shuriken, we make four of those and glued them all together. And the next one is we just fold the paper in such way so it’ll form a shuriken.

In the end, we’ll see the same result, but the advantage of doing it the second way, or by folding them is because we still had the original form of the paper as it is. This definitely will come in handy if we need to track down the original form of the paper, and this is what Time Travel looks like in Dan Abramov’s original presentation of Redux.

Imagine we got a mysterious error while developing the project, and we want to know when the state went wrong so we can fix it. With reducer function, we can just go back and forth through the timeline and see any states on any given time because we didn’t change the form of the state from the beginning, instead we “fold” them as every user action is happening. Magic, right?

Now that you understood about the concept of reducing function, i’ll continue to the core concepts of Redux.

Imagine that you have a water dispenser at home. I’m sure you know how it works right?

  • We connect the water dispenser to source of electricity at our home,
  • then we open the bottom lid where our bottle of water goes
  • get a large bottle of water and replace the old bottle of water inside the water dispenser
  • close the lid
  • and last, if we want to drink the water, we push the button on top of them so the water comes out and put it inside a Small Glass

Easy right? Now imagine that the water dispenser implements Redux inside their system, and we want to know what’s going on inside. Let’s take a look! P.S. we’ll come back to the flow above with it’s Redux version.

In Redux, there are three main components that made the redux system works. The components are Store, Actions, and Reducer. Which one’s which will be explained further below.

Store

Store is an object that held the current state of the machine. Every information that we need on the machine will be held inside a store. Aside than that, store also responsible to handle every components that want to know the current state or alter the current state.

On our water dispenser, a store will held informations like:

  • Electrical State (ON , and OFF)
  • Water Level State (1mL, 10mL, 100mL)
  • Bottom Lid State (OPENED, and CLOSED)

And we need to define the initial state of our machine. For instance:

  • Electrical State: ON
  • Water Level State: 0mL
  • Bottom Lid State: CLOSED

Action

Action is….. an action (lol). So action is an object that defines what action can we do inside a system and alter it’s state. But remember, an action doesn’t define how it’s supposed to alter the state, it just act as the semantic definition or enum. And, action could have parameters inside it if needed.

If we wanted to do an action, we’ll need to dispatch the action to the store, or simply we tell the store what action we want it to do.

On our water dispenser, the actions that we define would look like:

  • TURN_ON
  • TURN_OFF
  • OPEN_BOTTOM_LID
  • CLOSE_BOTTOM_LID
  • REPLACE_BOTTLE(New Bottle)
  • PUT_WATER_TO_GLASS(Glass)

Reducer

And last, reducer act as the definition of a particular Action. So there will be one reducer for each action we define inside the system. For the sake of simplicity, i’ll explain the reducer example in “Human Words”.

On our water dispenser, the reducer for each actions that we define would look like:

  • Action: TURN_ON
    Reducer: Sets the Electrical State to ON.
  • Action: TURN_OFF
    Reducer: Sets the Electrical State to OFF.
  • Action: OPEN_BOTTOM_LID
    Reducer: Sets the Bottom Lid State to OPENED.
  • Action: CLOSE_BOTTOM_LID
    Reducer: Sets the Bottom Lid State to CLOSED.
  • Action: REPLACE_BOTTLE(New Bottle)
    Reducer: Sets the Water Level State to Whatever the New Bottle Water Level State is (e.g. 5000mL so Water Level = 5000).
  • Action: PUT_WATER_TO_GLASS(Glass)
    Reducer: Decrease the Water Level State with the volume needed by the Glass(e.g. 650mL so Water Level = Water Level-650).

Now that we know 3 components of Redux, we’ll try to translate the flow of Water Dispenser stated above.

  • Original: We connect the water dispenser to source of electricity at our home.
    Redux Version: Dispatch TURN_ON action to the store.
  • Original: then we open the bottom lid where our bottle of water goes.
    Redux Version: Dispatch OPEN_BOTTOM_LID action to the store.
  • Original: get a large bottle of water and replace the old bottle of water inside the water dispenser.
    Redux Version: Dispatch REPLACE_BOTTLE action with Large Bottle of Water as parameter to the store.
  • Original: close the lid.
    Redux Version: Dispatch CLOSE_BOTTOM_LID action to the store.
  • Original: and last, if we want to drink the water, we push the button on top of them so the water comes out and put it inside a Small Glass.
    Redux Version: Dispatch PUT_WATER_TO_GLASS with Small Glass as parameter to the store.

And Voila! you just learned the very core concept of how Redux works. It’s not that hard right? and we can simply translate every user action to a Redux action and implement them in our projects.

Alright, last i want to explain about 3 principles of Redux. There are 3 main principles of Redux that we need to know, there’s Single source of truth, State is read-only, and Changes are made with pure functions.

First, Single Source of Truth. This means that we should only store one state object on our application, no more, no less. Why is that so? if we have more than one state on our application lifecycle, it’ll be much harder to debug when things go wrong. Imagine you found a bug, and you split the state of your application into five different state. Then, if you want to trace when is the state are producing the error, you need to go through those five states. Makes sense, right?

Second, State is read-only. This goes back to my explanation about reducing function and why it’s magical. We should never change our state object with a brand new state object right from the oven. Instead, we should only change information(s) that needs to be changed. If you have a hard time understanding this, imagine that changing the state looks something like appState = newAppState where changing only specific informations looks something like appState = newAppState.copy(electricalState = ON)

Last, Changes are made with pure functions. This means that reducer functions should be in a form of pure function that takes current state, and what action it would do, and will produce the altered action as the result. Reducer function should not act more than this, it’s because when we add something more to the reducer function (e.g. we add more params or something to the function), it’ll be harder to unit test those. So keep that in mind, keep the reducer function as simple as it should be.

There you go! I hope right now you already get a good grasp on how Redux Core Principle works. Of course there’s still more of Redux for you to learn, like Middleware and Asynchronous. But, we’ll save it for later, probably i’ll explain about more advanced principles or how to implement redux in one of your projects on the next article. And, if you want to find more about Redux, there are a lot of resources available on their official website.

I hope you’ve find this article useful. If you have any suggestion on my explanation above, feel free to comment down below.

Thanks for reading!

Have a good day!

--

--

Angga Dwi Arifandi
The Startup

A passionate Software Engineer who's curious about everything.