Redux isn’t exactly Flux, but it is Flux-like. Redux simplifies the approach to Flux by removing the need for a dispatcher by having only one store. In Redux, state is stored in a single location and modularity is achieved through pure functions called reducers.
- [Narrator] Redux isn't exactly Flux, it's Flux-like, and Flux data flows in one direction. An action is sent to the dispatcher, and then dispatched to one or more stores before the view is updated. And Redux data still flows in one direction, but there's a big difference. There's only one store. With Redux you cannot use multiple stores, and because there is only one store, there's no need for a dispatcher. The store will dispatch the actions directly. Having one stores means that all of your state will be located in one place. We refer to this as the single source of truth.
For example, let's say we have a social media application. All of the data for one client can be stored in a single object. Everything we need to know about the current state of our application is right here. We have user information, along with their preferences, information about posts, friends, and we even have an array to save information about errors that could have occurred. Storing everything in one place makes it much easier to reason about the data within our application, and since we have all of the data here, it should make it a little easier for us to track down bugs too.
Now at this point you may be thinking that we lose modularity by storing all of the data in one object. One object does not sound very modular. But with Redux, modularity is obtained through functions. Instead of breaking the state up into different objects, we will create functions that are designed to manage specific leaves and branches of this state tree. We'll have a function to manage the user part. We'll have another function to manage an individual post, and one to manage an entire array of posts. We could probably reuse the user function to manage our friends, but we may have a friends function to manage the entire array of friends.
And we would even have an error function to manage the array of errors. The idea of using functions for modularity comes from the functional programming paradigm. It's the paradigm that was used to develop Redux. Now you don't have to be an expert in functional programming to work with Redux, but there are a few important concepts that you want to keep in mind. The first are pure functions. Pure functions are functions that do not cause side effects. Everything the function needs to operate is sent as arguments, and a new result is returned. Pure functions do not change any of their arguments or any global variables.
They simply use the information to produce a new result. That brings us to our second point: immutability. To mutate is to change, so to be immutable is to be unchangeable. We do not want to change the variables and objects in a functional application. Instead we want to produce new ones. The third and final point is composition. Composition refers to the ability to put functions together in a way that one function's output becomes the next function's input. This means that the values returned from one function become the arguments of the next function, until eventually the last function returns the value we were looking for.
Let's take a look at composition by examining the getPercent function. Let's assume we have a function that we can send one and four to, and it will return 25%. This function could be composed of smaller functions, so when we send one and four as arguments to getPercent, they become the arguments that are sent to convertToDecimal. Now the convertToDecimal function will return 0.25, and the value returned by convertToDecimal becomes the arguments for decimalToPercent, which will then take that value, multiply it by 100, and give us 25.
Now the output from decimalToPercent will become the input for addPercentSign, and a percent sign becomes concatenated onto our value. Eventually 25% is returned. This is the idea behind composition. In Redux, composition is used in the store. The reducer functions that we create to manage specific parts of the state tree are composed, and the action and state is sent to and piped through each of these reducers until a state is eventually mutated. Now we don't have to worry about how these reducers are composed.
All we have to do is identify state, write good reducers, and let the Redux store handle the rest.
- What is Redux?
- Building object and array reducers
- Combining reducers
- Creating a store
- Creating middleware
- Building action creators
- Incorporating React components