‫Let's now implement
‫the missing functionality of this application,
‫which is to actually make these buttons here work
‫in order to manually adjust the duration.
‫So, right now, the duration here adjusts
‫each time that we set one of these states, right here.
‫So hopefully, you analyze that
‫when you first checked out a code.
‫So notice how we have four pieces of state here,
‫one for the number.
‫So this one.
‫Then for the sets, for the speed,
‫and for the duration of the length.
‫And so then, the duration here is a derived state,
‫which is on every render calculated
‫from these four state variables right here.
‫And so that's what we then get here.
‫So, of course, as soon as we update
‫one of these state variables,
‫the component re-renders,
‫and then the duration gets recalculated and displayed here.
‫So that's just very common stuff
‫that we have been doing all the time.
‫But now, again, we actually want to make these buttons work.
‫So we want the duration to update
‫as a result of clicking these buttons.
‫And so that means that the duration now
‫needs to be a new piece of state.
‫So, let's do that.
‫So let's comment out this one,
‫and place the duration in state.
‫So duration and setDuration
‫is useState.
‫And let's start at zero.
‫So we can not simply place this formula right here,
‫because it would only be called on the initial render.
‫Remember that.
‫And so that's not what we want.
‫Of course, we will want to calculate this duration
‫each time that we click on one of these buttons,
‫but also each time
‫that one of these state variables here changes.
‫So just like it was working before with this derived state.
‫And so now, we need a way
‫of getting this functionality back.
‫So basically, of updating the duration state
‫each time one of these state variables here updates.
‫Now there are two ways in which we could do this.
‫So we could update the duration
‫each time that we update one of these
‫in the event handler function.
‫So basically, we have, of course,
‫one event handler for each of them.
‫For example, here is the one for the number.
‫Here is the one for the number of sets.
‫So for this one right here.
‫And then these are the ones down here.
‫So one event handler function
‫for each change event on each of these input elements.
‫So as I was saying, we could now,
‫in each of these event handlers,
‫not only update the state that it is about,
‫but also the duration state.
‫So for example, here, besides doing that,
‫we could then also
‫set duration
‫and then copy that formula over here.
‫Let's actually just do this here as an example.
‫So, this is not the solution that we're going for,
‫but I just want to exemplify this.
‫So now, here, of course,
‫we cannot use the break here because it is still stale.
‫So, the update only actually happens after the render,
‫as we have talked about many times before.
‫So here, we would even have to use e.target.value.
‫And so let's see.
‫And so that would actually work, right?
‫But we would then have to do this
‫in every single event handler.
‫So repeating all this code all over the place.
‫So instead of doing this,
‫we will now again use the useEffect Hook
‫to basically synchronize these states with one another.
‫So, just fixing this year seems a bit complicated.
‫All right.
‫So, what we're going to do now, as I just said,
‫is to use the useEffect Hook
‫to keep this duration state here in sync
‫with all these other state variables.
‫Now, notice how I said earlier in that long lecture
‫about the useEffect Hook,
‫that this is exactly what we usually should not do.
‫However, I think that in this situation,
‫this is a perfectly fine use case for the useEffect Hook,
‫because there are so many state variables here involved,
‫that it just becomes very impractical,
‫and even unreadable and confusing to do it in a way
‫that I just demonstrated you.
‫And so again,
‫we should instead use an effect in this situation.
‫Okay.
‫And the dependency array, we can already write it ourselves
‫so that we understand why we actually need this effect.
‫So here, we will want to set the duration
‫whenever the number changes,
‫or when the sets change,
‫or when the speed changes,
‫or when the duration of the break changes.
‫All right.
‫And now, here, we then need that actual formula.
‫So, exactly this one right here.
‫And so, then, we will be back
‫to the application working in the exact same way as before.
‫So everything works here.
‫And so now, with this in place,
‫we can implement these two buttons,
‫which of course still don't work,
‫but we first had to do all of this here
‫so that we could now then also set the duration state
‫when we click on those buttons.
‫So let's actually write separate event handler functions
‫in this case.
‫So function handleInc, let's say.
‫And so, here, we get the current duration
‫and we want to return the duration plus one.
‫So at least for now.
‫So let's find the button here.
‫Yeah. So, right here.
‫Let's now replace this dummy function with handleInc.
‫And so...
‫Yeah, that works.
‫Nice.
‫Now, let me just show you something.
‫So, I'm trying to find a situation where, here,
‫we have half a minute, and...
‫Ah, so here is one of the situations
‫where we have half a minute.
‫And so in this case, when we click on this button,
‫we actually want to round it to the next value.
‫So the next entire value.
‫So that would be 83, in this situation,
‫and not 83 and 30 seconds.
‫So what we can do is first,
‫round that down with Math.floor.
‫And yeah, so now that works.
‫Okay.
‫And now let's also create handle decrement,
‫handleDec.
‫And here, we're gonna do the opposite.
‫So we will first round up the current duration,
‫and then we will subtract one.
‫And so now, this will first round it up to 80,
‫and then from there we go down to 79.
‫Now, of course, we need to wire this up.
‫So place that function here.
‫So handleDec.
‫And so, again, it'll now go down to 79.
‫Now, the problem is that
‫if this is really slow or really low, actually,
‫then, of course, we go to negative values.
‫So let's fix that.
‫And so here, let's use a ternary.
‫So if the duration is still greater than one, then do this.
‫But otherwise,
‫then the next duration will be zero.
‫All right.
‫And one minute and zero, and we can't go below that.
‫Nice.
‫So at this, we implemented what we set out to do.
‫So these buttons now work.
‫And again, in order to do that,
‫we needed to transform this duration here
‫into a state variable.
‫And so then, to update that state variable in an easy way,
‫we created this effect which lists for the state change
‫in any one of these four state variables.
‫And if that happens,
‫it will then calculate our new duration.
‫And so, here, we have the classic example
‫of using an effect to update state
‫based on another state update,
‫which again, is not always desirable
‫and it's not always the best solution.
‫But here, I think it is perfectly fine
‫because otherwise, we would have to spread this logic here
‫into four different event handler functions
‫which wouldn't be really nice.
‫Now, let me actually show you the downside here.
‫So using the profiler,
‫so let's start,
‫and then I will just adjust this date once.
‫So one state update, right?
‫Well, we now get all these date updates
‫because of the timer they're updating.
‫So let's maybe turn that off, actually, just for a minute.
‫So let's do this.
‫Let's do this again.
‫So, only updating once, which we would think
‫only gives us one render.
‫But actually, we do have two renders.
‫So the calculator is rendered.
‫And then again, and so this is exactly the problem
‫of the useEffect Hook to update states.
‫So, right here.
‫So basically, this first state update
‫is this number of sets updating,
‫which will then trigger this effect here.
‫But the effect only runs
‫after the render has already happened.
‫And so then when we set the state here again,
‫we get a second render.
‫So React is not able to batch these two renders in one,
‫simply because, again, the effect actually runs
‫way after the render has already happened.
‫And so just be aware of that issue
‫whenever you do something like this.
‫So, whenever you can, again, avoid this.
‫But when you have so many state variables here
‫that influence the value of another state,
‫then you can do this.