Redux From Scratch (Chapter 1 | Core Concepts)
Buy the Official Ebook
If you would like to support the author and receive a PDF, EPUB, and/or MOBI copy of the book, please purchase the official ebook.
Prerequisites
Understand the fundamentals of React, ES6, and the basic build of a React application (NPM, Webpack, Babel).
If you have not learned React yet, here is an ebook I wrote called React.js for the Visual Learner.
What to Expect
Before I begin any teaching on Redux, I want to clarify the format of this book and my teaching methodology.
I am on a mission to teach Redux as practically as possible from scratch. I am able to be super practical because I am writing this book as I am learning Redux myself. Meaning, when I have those “a-ha” moments where something clicks. I can explain to you exactly what made it click for me. I will be using stories, analogies, and visual-friendly examples to reiterate what I am learning.
Because I emphasize practicality in all my writing, I usually have the tendency to err by going into too much explanation than not enough. It really grinds my gears when people teach on a subject and make all sorts of assumptions. Besides the prerequisites shown above, I will do my absolute best to not make assumptions for the “not so obvious”.
A very important point to make upfront is that I am aiming this book is intended for pairing Redux with React.
As far as format, I’m going to spend the first couple of chapters with a lot more text than coding. Reason being, it’s going to be focused on driving home the major concepts. As we get start the coding, I am going to be doing “behind the scenes” coding. Meaning, I am going to be using online editors where we can create small code snippets to learn the basics of Redux without getting distracted by the build of a project. After we cover the basics in small pieces, we will create an entire project from scratch that gives us a solid introduction to working with React and Redux. We then go beyond into working with Firebase, tackling more advanced Redux concepts, and creating a final project that incorporates an API service. By the end of this book, you should have a solid understanding of how to work with React, Redux, Firebase, Express, and MonogoDB in a real-world scenario. I am doing this to make further progress in my development career and it is my desire that it would have the same impact on you as well.
With all this aside, let’s begin the journey!
Why Use Redux?
According to the official documentation, Redux is a predictable state container for JavaScript apps. It is agnostic to React, however, we are going to be looking into its use cases and benefits for use with React.
Redux is probably a buzz word that slips into the lingo of React developers. If your reaction has been like mine, it’s always been one of those things where I didn’t know much about it other than this official definition. I never could answer: “Why should I use Redux?”
Admittedly, I had looked up the Redux documentation before. However, I skimmed the documentation very quickly, went straight for the code, and then I thought: “This looks confusing. Well, my React projects are doing fine. I will put this aside for another time.”
Let’s take the time to really understand why we need to learn Redux before we move forward.
The main thing to keep in mind about Redux is that is an alternative way to manage state in a React. By state, I mean the this.state = {...}
stuff that you see in an ES6 constructor:
class NormalReact extends React.Component {
constructor() {
super();
this.state = {message: "This is a local state."};
}
}
The local state is used for controlling data that will be updated in your application. If multiple children components need something from the local state, you could pass the data from the state down as a prop:
All data in React flows downward. The example in the diagram is very simplistic. However, React applications will get more complex.
There will be use cases where a child will also need to have its own local state:
As applications grow in complexity, the more local states that you will have to keep track of.
There’s also times where you might have initial setup your app to work like this:
The child is managing a local state.
Let’s say you still only needed one state but the parent will have more children that you didn’t initially plan for.
You’d have to rewrite your code to bump the local state up one level:
Redux provides an alternative to handling state. It contains all of the states in a central location:
Any of the components can access the states and their data. Redux also allows us to trace which component is accessing which state and what did they do with it.
In case this still is a bit confusing, let me use an analogy.
Let’s say a real-life parent has real-life children. The parent has all of his money as cash in a room within his home. The children need money but they can’t provide any income. Therefore, the money always flows down. For the sake of example, let’s also say that there is no automatic way of tracking this cash flow.
Let’s say one child gets a bit wiser and decides to save up the money being inherited. He also passes down the saved up money to be invested in other places.
The cash flow for this entire family is getting to be too complex to manually calculate.
The equivalent of Redux in this scenario would be to move all the accounts within this family to a bank:
Everyone in the family has been granted access to go to a teller and request an update to the data (checking or savings) in any of the accounts. You would also have a receipt from the teller for all transactions specifying who did what and what do the accounts currently look like.
Don’t go too far down the rabbit hole of any of these explanations. The main gist is that Redux is an alternative way to manage states within a React application as it moves the states to a separate container.
Core Concepts
Terminologies
There are 3 main terminologies to understand:
- Store
- Actions
- Reducers
To explain these, let’s compare it to our bank example which is a good analogy of how Redux works:
You go to a bank and request an update to the checking account within your personal account. Knowing this information, the teller updates the specified account (your personal account) and the account type (checking). The teller then provides you a receipt of how much money is left in your personal account.
In a React and Redux application, the bank that stores the accounts is equivalent to a store. A store contains all of the states within the application. Each state has its own data that can be accessed.
Within the application, there will be two main types of components when implementing best practices: active and static. Active components are doing the work to manage the data in a state. Static components are simply presenting using the inherited data (props). In other words, active components care about how things work and static components care about how things look.
Note: Active and static components is my own terminology. However, the official documentation calls them container and presentational components. The official terminology will make more sense when we get into the code so for now I will maintain my custom terminology.
For example, let’s say we wanted to render this Twitter card containing my profile information in 2 components. The active component would go to the state and retrieve the data about by Twitter username. All that data would be passed to the static component which presents the final Twitter card.
The active components are going to be requesting data from states within a store and providing the data to static components. Therefore, we can refer to the active components as providers. Note: Providers is not official terminology but I find it helpful to use it.
Back to our bank analogy, the providers are the equivalent of you coming into a bank. The request you make to a teller to update the personal account (i.e. withdraw from checking) is the equivalent of an action. In Redux, actions are the dispatched requests from the providers to update a state within the store.
The graphic above should be slightly tweaked because there are middlemen that hear the dispatched actions and handle them accordingly.
These middlemen are called reducers. Reducers listen to the dispatched actions and perform a certain action on the specified state. The current information about the state is then given to the providers.
Now, there can be many actions dispatched at once. The name reducers comes from the fact that many actions can be “reduced” into a single new state.
To recap:
- Stores contain all the states within your application
- Active components (which I like to call providers) request/dispatch actions to be handled on a specified state
- Reducers apply the requested action on the state that was specified
Principles
There are two main principles behind Redux.
The first principle is that there is only one way to update a state, dispatching an event.
Meaning, the provider must dispatch an action to the reducer. It can’t go straight to the store update data. Likewise, you can’t go to a bank and update your personal account yourself. You have to go through a teller.
The second principle is that changes are made with pure functions.
Technically, even the reducer won’t just mutate the previous state. Instead, it takes the previous state, applies the action, and returns a new state.
Managing state in React without Redux follows the same pattern. You don’t just do this.state.color = "blue"
. You have to do this.setState({color: "blue"})
for a simple update. Or, for an update that requires the previous state’s information, you would do:
this.setState((prevState) => {
return {counter: prevState.counter + 1};
});
In the React examples without Redux, we use the setState API. The React library does the heavy lifting. With Redux implemented, we will write out our own pure functions in place of the setState API.
Concluding Thoughts
I purposely wanted to explain the core concepts of Redux without looking at Redux code. This results in you understanding the concepts on a conceptual level instead of looking at code and thinking: “This sure looks intimidating!”
In the next chapter, we are going to take these core concepts and do some small bits of coding together. We will leave the build setup “behind the scenes” and just focus on being introduced to Redux code. We will code this in vanilla JS before moving on the an implementation with React in chapter 3.
Another thing. Please keep in mind that I am writing this as I am learning. Feel free to leave comment or private note :)
Resources
Redux Official Documentation
Presentational and Container Components by Dan Abramov
Chapter 2
Buy the Official Ebook
If you would like to support the author and receive a PDF, EPUB, and/or MOBI copy of the book, please purchase the official ebook.
Cheers,
Mike Mangialardi