‫Of course, let's now use the idea
‫of derived state in practice.
‫And in particular
‫we now want to calculate our statistics here.
‫So calculating the number of items on the list,
‫how many we already have packed
‫and then the percentage of that.
‫Now, if we think about these numbers,
‫for example, the number of items in the list,
‫that number can be directly computed
‫from the items array itself, right?
‫And so derived state is perfect for this,
‫but before we use derived state
‫I will show you how not to do this.
‫So the way we should not do it is to use state.
‫So let's say we created a piece of state called numItems
‫and then setNumItems.
‫And by the way,
‫you don't need to write this code right here, all right.
‫So this is just to show you how not to do it.
‫So initially we start with 0 items.
‫Now the problem with this is, as I said before,
‫is that we now have to also update this piece of state.
‫So whenever, for example,
‫one new item is added, besides setting the items,
‫we also need to make sure to increase this number here.
‫So setNumItems and then the number and then num plus 1.
‫So with this, we would ensure that these two pieces of state
‫stay in sync, but that's of course a lot of additional work
‫that we might forget to do
‫and also it can cause multiple re-renders
‫where at least one of them here is unnecessary.
‫Now in React 18, these should be batched.
‫So these two should happen at the same time,
‫but more about that later.
‫But in any case, this is a terrible idea.
‫So instead we can just define a new variable
‫called also numItems, but we can simply derive it
‫so we can calculate it based on the items array.
‫So that simply items.length
‫and so this works because as soon as the items are updated,
‫so as soon as this piece of state is updated,
‫the component will re-render.
‫And when the component re-renders
‫that means that the function here is called again.
‫And therefore then this piece of code here will run again.
‫And so if a new item has been added then now the item state.
‫So this array is different
‫and therefore the length will also be different.
‫Now this numItems variable,
‫we actually don't need it right here in the app component,
‫but in the stats component.
‫So this one right here.
‫So we have two options now.
‫The first one is to keep numItems here
‫and pass it as a prop into stats,
‫but I think what makes more sense
‫is to actually calculate this state here.
‫So this derived state inside the stats itself.
‫Also because we will actually calculate three values
‫and so if we were to calculate them here
‫then we would have to pass three props
‫which doesn't make a lot of sense.
‫So let's just cut that from here
‫and paste it here into the items.
‫Well, actually no, that's not correct.
‫Want to paste it right here.
‫But now as soon as I save this, we will get an error, right.
‫And so the reason for that is
‫that now of course we don't know,
‫so this stats component doesn't know anything
‫about what this items is.
‫So we now have another component that needs the item state.
‫So we just pass it down as a prop.
‫Just like we passed it also into the packing list.
‫Now of course, we need to accept that prop down here
‫and so this solves the problem.
‫And so here we can now already use that value.
‫So you have numItems on your list
‫and so yeah, indeed, right now that's zero,
‫but if I add some socks here and maybe a shirt
‫then you see as soon as we add new items here,
‫the array grows
‫and so then this number here also gets updated.
‫So watch what happens when I hit enter
‫and immediately this changed from 2 to 3.
‫Let's just quickly remove those console.logs there.
‫So that's much better
‫and so now let's derive our other pieces of state.
‫So of course this one here,
‫so the ones that are already packed
‫and the percentage both depend on the items themselves.
‫So number of packed is simply the items array filtered
‫by the items that are already packed.
‫So item.packed.
‫So that's a new array
‫and so then we can take the length of that one.
‫So you have already packed number of packed
‫and so that immediately becomes 0,
‫but then when we mark one of them as packed.
‫Ah, beautiful.
‫So two, and then all of them.
‫Great.
‫And now finally just the percentage
‫which should be pretty easy.
‫So that's just a number of packed
‫divided by the number of items times 100
‫and then let's grab all of that and round it.
‫So Math.round
‫and so here then we can replace that.
‫Nice, that also works.
‫And now it hits 100%.
‫And in that case, so whenever we have 100%
‫I would like to display an entirely different message here.
‫So telling them basically that they are done.
‫So watch what happens here in the demo.
‫Yeah, that's it.
‫So let's write that here
‫and so for that, we need some more conditional rendering.
‫So actually we will just conditionally define what is here
‫inside this em element.
‫So let's enter our JavaScript mode
‫and say that whenever the percentage is equal to 100
‫then the content should be this string right here,
‫"You got everything! Ready to go."
‫Now let's add a plane emoji here as well
‫and now else
‫and so let's move that here.
‫And so now instead of this text that we had here,
‫we now need a string.
‫And so let's make a template literal here
‫and then we need to add of course, these.
‫And in case we didn't want to create this template literal,
‫we could of course also have simply rendered one em
‫for each of these cases.
‫Now, this looks not correct,
‫maybe it's because of this right here.
‫Yeah, but it looks at as though it works
‫even though we are in the wrong app.
‫Ah, but here we already have our correct message.
‫Let's uncheck one of those
‫and now you have three items on your list.
‫Great.
‫Now let's remove this one and this one as well.
‫And so now we have already packed zero
‫and also in this case
‫I want to display something else as well.
‫So also another message.
‫So if this is the case,
‫if there are not even any items in the array,
‫then it's not even necessary actually
‫to perform all these calculations
‫because they will just be zero anyway.
‫So what I want to do now here is to show you a good use case
‫of an early return as conditional rendering.
‫So what we're going to do is to say
‫if there is no items.length,
‫then simply return.
‫So that's return a paragraph with the class of footer
‫and then here also an em
‫and then start adding some items to your packing list
‫and again, some nice emoji here, like this rocket.
‫And so now let's reload this here
‫so that we then have no items.
‫And so yeah, here we go.
‫Now here the class name is not footer, but stats.
‫So basically the same as here.
‫And so yeah, then we got this.
‫So this text that we defined right here, so this paragraph,
‫and again that's because in this case
‫it doesn't even make sense to then do these calculations.
‫So if there are no elements anyway in the array
‫then don't even bother with all of this here.
‫Now in this case, of course
‫it would've been no problem to still do these calculations
‫as they are not a lot of work
‫and we could then have some conditional rendering in here.
‫But this was just to show you
‫that the option of an early return is sometimes also nice.
‫So it's also quite legible here if you ask me.
‫So when you arrive at this component
‫maybe you have never seen it before
‫because one of your coworkers wrote it,
‫then you can right away see that if there are no items,
‫well then just return this
‫and in all other cases then perform the rest of the logic
‫of the component.
‫Great. So hopefully that made sense
‫and so next up, let's see another use case of derived state
‫which will be to implement this sorting functionality here.
‫So that will make this application look even more real life
‫and so I think this is going to be really fun.