Check out a free preview of the full Redux Fundamentals (feat. React) course
The "Deriving Data" Lesson is part of the full, Redux Fundamentals (feat. React) course featured in this preview video. Here's what you'd learn in this lesson:
Steve walks through computing and deriving data without storing data in state using mapStateToProps. The mapStateToProps function can take in props as arguments and return a newly computed value while avoiding storing extra data in state.
Transcript from the "Deriving Data" Lesson
[00:00:00]
>> So now we have the next question which is, we were able to manage all the state in our application. But what about like the end results, the total price for a given item based on the price and the quantity, the sub-total of all the items. To the Tip Amount, which is multiplied by a decimal based on the tip, and then the total which has the Subtotal on the Tip Amount.
[00:00:26]
One of the things that I have seen that I would like to have a word with everyone about. Is I have seen times where the approach is to then all right, what I'm gonna do is, I'm gonna store the subtotal in state. And I'm gonna store the tip amount, I see some eyebrows already going like that's the right [LAUGH] yes, his head's shaking all right.
[00:00:46]
I'm gonna store that stuff in state and then I'm gonna try to update it when everything changes. That you will lose days of your life when you eventually make some kind of mistake and can't keep all those pieces of data in sync. So the rule that I would like to implant in your brain is, only store the stuff you need to.
[00:01:08]
In the same way for our actions, as little as we can get away with in the action. I would like to store as little data as possible in the actual store itself. Anything that I can figure out by taking two or more pieces of data and combining them, I will figure it out on the fly.
[00:01:32]
Now, a common complaint that I get is, well, what if it's like we're gonna multiply some numbers in this application, let's be real clear. But you can see as well it's very expensive. So we should just hold on to it and we just store it in state. We have a solution for that.
[00:01:48]
We will get to that in a second, right? Again, a lot of times we should actually solve the real problem, not just grab for the most obvious answer. So we'll look at like how to actually mentalize and cash values and a little bit. But first of all, the other thing that we can do in map state to props, is use the ability to take two maybe, for instance, the Total, right?
[00:02:12]
That's not stored in state, but map state to props can also do some of that figuring out what the props should be that gets passed in based on the actual state as well. It doesn't just have to take the item from our store and then pass it in, or whatever.
[00:02:27]
It can also figure stuff out and map it to the value that this particular component needs. So if we look at the Sub-total Tip Amount, those are props that the summary component takes, we don't need to store a sub-total instead. We can go figure it out. Based on the data that's in the state and pass it into the component as a prop using map state to props.
[00:02:50]
So I'm gonna create a summary container in here and we'll go call it SummaryContainer.js. And we'll start with this mapStateToProps. MapStateToProps is going to take instance of all the state that we have. And then really we need to figure out the subtotal. Anyone have a quick and easy way, there's multiple ways that we could do this.
[00:03:23]
I will live code the first one, that is easily live codable that one of you volunteer.
>> Are you saying that we should go over, and see the quantity and of the items times their price?
>> Yeah just add them together.
>> Yep, but I need all of them together, so I need not only ,this is the entire bill.
[00:03:43]
So I need any given items total price and then I need all of them together.
>> So I guess what you're saying is, should we iterate over the items?
>> Yep.
>> And then just sum them up.
>> We can iterate over some, we can use reduce, which one makes me happier?
[00:04:02]
>> Reduce doesn't make me happy. [LAUGH] [CROSSTALK] But that's just because I'm kinda a novice. But either way, [CROSSTALK]
>> Let's go.
>> Let's say that subtotal will start at 0. Let's iterate over it. And then we'll store items here just make it easier for us. Items is state.items, right?
[00:04:26]
And then we will go through and we'll say, for const item of items. We'll go through and we'll say subtotal plus equals and when see something wrong with my logic. Just call it out. Subtotal it will equal the item.quantity times item.price. Right on, yeah, we're not using it yet, I will.
[00:05:01]
And so we'll go through and, if we look at the summary component needs a few other things. It's expecting the subtotal, the tipAmount and the total. So we've got that. If we go ahead and we look in our state, we can see a tipPercentage is stored as a whole number as state.tipPercentage.
[00:05:24]
So we can grab, right? We've only grabbed one thing at a time, we have the entire state tree available to us. We can use the entire state tree and this is useful for computing data. So all right. So, will say, the const tipAmount will be that subtotal Times the state.tipPercentage Divided by a 100.
[00:06:01]
And finally the total is simpler. That one's easy. It's just gonna be subtotal plus tipamount. So here we don't have a tipAmount or a total or subtotal stored in state, but this is what the component is expecting. So we can just given the props at once. Using map state to props, we are taking different pieces of state.
[00:06:22]
We'll say cool, you're gonna get a subtotal, you're gonna get a tipAmount and you're gonna get a total, great. So we have all that in place, and now we just need to pass it into the component itself. So we'll say export const Summary Container, Is equal to connect.
[00:06:51]
And we'll do this mapStateProps. If you really wanted to pass this function in as the first argument you could. If it's really simple you might be able to, but I wouldn't. And then we can say the Summary component that we have, As well. And now we've just gotta swap out in our kinda main calculator here, Summary for SummaryContainer.
[00:07:20]
We'll see if I made any mistakes. This will be a ../containers. All right, let's see what we got. We'll give it a good refresh. One small issue as I had, after joking about eventually misspelling quantity, I misspelled quantity. So we go back. We can see that we've got everything kinda in place here.
[00:07:46]
I made allusions to, like this is simple. We're adding numbers. We're multiplying numbers, right? We're kinda taking pieces of our state, manipulating it in the way that the component expects. And returning the props of that component wants based on the state from redux. The reference of maybe four is like this is fine for multiplying adding numbers.
[00:08:06]
What do we do if things get a little bit more expensive? And we think about what we know about react. We know that there are patterns around this, like earlier we saw use memo and even use effect. We can see like most of those API's and react, take an array of things that say hey, don't call this again unless something in this array changes.
[00:08:31]
In react for use callback and use memo. We're saying like no matter how many times this hook gets called. Unless something in this array is different than the last time you called it, don't even try to compute any values. Just give me back the same thing you got last time.
[00:08:47]
And that solves a lot of our problem around like whatever this is an expensive thing, so on and so forth. And there's some other powerful parts of the pattern we're gonna talk about, which is going back to this idea of using selectors. But there is a library that is frequently used with reactor called reflect.
[00:09:06]
And reselect allows you to do is very similar with that array like syntax. For caching values that we've seen in use callback and use memo. And I guess to an extent use a fact and react and allows us to use it. And again, since it is just regular JavaScript and redux, it allows us to use it with redux as well.
[00:09:26]
A lot of things we're talking about is just simply a pattern implemented using just functions and objects. So things that work with just functional objects will work with redux. And so we'll kinda talk through this a little bit. We're gonna reimplement some of this logic here as well.
[00:09:43]
One of the things that we saw in the chat was like okay, what does the reduced version of this look like as well? And we can do that too, which is simply if we wanna do const subtotal, would be items.reduce. We'll take the sum, the item that we're working through and we will return, Sum plus.
[00:10:23]
Item.price. I don't need the prices. Item.price times item.quantity. And with a starting value of 0, right? So we could theoretically unless I made a mistake, swap it in whichever syntax you like more, they both basically do the same thing. I'll just refresh that real quick. Everything still works, whichever syntax makes you happier.
[00:10:50]
This works through the array, accumulating all the return values of each function to the sum starting at 0. So each time we add in the sum plus the next item, whichever one it's totally fine me
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops