‫So we just learned how to use the useReducer hook
‫to centralize all the state updating logic
‫in one central place, which is the reducer function.
‫So let's now dive deeper into the concept of reducers
‫and how and why they can make our applications
‫a lot better in certain situations.
‫So up until this point,
‫we have been using the useState hook
‫to manage all our state, right?
‫However, as components and state updates
‫become more complex, using useState to manage all state
‫is, in certain situations, not enough.
‫For example, some components have a lot of state variables
‫and also a lot of state updates
‫that are spread across multiple event handlers
‫all over the component or maybe even multiple components.
‫And so this can quickly become overwhelming
‫and hard to manage.
‫It's also very common that multiple state updates
‫need to happen at the same time
‫so as a reaction to the same event.
‫For example, when we want to start a game,
‫we might have to set the score to zero,
‫set an is playing status and start a timer.
‫And finally, many times updating one piece of state
‫depends on one or more other pieces of state,
‫which can also become challenging
‫when there is a lot of state.
‫And so in all these cases, useReducer can really help.
‫So these are the problems that reducers try to solve
‫and so let's now see how.
‫So first of all, useReducer is an alternative way
‫of setting and managing state,
‫which is ideal for complex state
‫and for related pieces of state.
‫Now, we already used useReducer in the last two lectures
‫and this is what that looked like.
‫So we call useReducer
‫with a reducer function and its initial state
‫and it returns a state and a dispatch function.
‫So starting from the beginning, when we use useReducer,
‫we usually store related pieces of state
‫in a state object that is returned from the useReducer hook.
‫Now, it could also be a primitive value
‫but usually, we use objects.
‫Now, as we already know, useReducer needs something called
‫a reducer function in order to work.
‫So this function is where we place all the logic
‫that will be responsible for updating the state
‫and moving all state updating logic from event handlers
‫into this one central place allows us
‫to completely decouple state logic from the component itself
‫which makes our components so much cleaner
‫and so much more readable.
‫So when we manage state with useReducer,
‫it's ultimately this reducer function
‫that will be updating the state object.
‫So in a way.
‫it's a bit like the setState function in useState
‫but with superpowers.
‫Now in practice, the reducer is simply a function
‫that takes in the current state and an action,
‫and based on those values, returns the next state,
‫so the updated state.
‫Now, keep in mind that state is immutable in React.
‫This means that the reducer
‫is not allowed to mutate the state,
‫and in fact, no side effects are allowed
‫in the reducer at all.
‫So a reducer must be a pure function
‫that always returns a new state.
‫And again, based on the current state
‫and the received action.
‫And speaking of the action, the action is simply an object
‫that describes how state should be updated.
‫It usually contains an action type and a so-called payload
‫which is basically input data.
‫And it's based on this action type and payload
‫that the reducer will then determine
‫how exactly to create the next state.
‫And now the final piece of the puzzle is this.
‫How do we actually trigger a state update?
‫Well, that's where the dispatch function comes into play.
‫So useReducer will return a so-called dispatch function
‫which is a function that we can use
‫to trigger state updates.
‫So instead of using setState to update state,
‫we now use the dispatch function in order to send an action
‫from the event handler
‫where we're calling dispatch to the reducer.
‫And as we already know,
‫the reducer will then use this action
‫to compute the next state.
‫Okay, so these are all the pieces that need to fit together
‫in order to effectively use the useReducer hook.
‫So an action object, a dispatch function, a reducer,
‫and a state object.
‫But now let's also look at the diagram
‫to really see how all of these pieces actually fit together
‫in order to update state.
‫So let's say
‫that we're in an event handler in some component
‫and we now need to update some state.
‫So what do we do? Well, that's right.
‫We call the dispatch function
‫that we got back from useReducer
‫in order to dispatch an action to the reducer.
‫And this action, as we learned before,
‫is an object that contains information for the reducer.
‫So information about how the reducer
‫should update the state.
‫In this case, the action type is updateDay
‫and the payload is 23, which probably means that the reducer
‫will set the day state to 23.
‫Now, the object doesn't need to have this exact shape
‫with a type in the payload, but it's a standard
‫that has been adopted by most developers.
‫Now basically, the reducer takes in this action
‫together with the current state
‫and it will then return a brand new state object
‫which we usually call the next state
‫in the context of reducers.
‫And as always with state,
‫updating state will then trigger a re-render
‫of the component instance.
‫Now, if you're wondering why the reducer function
‫is actually called a reducer,
‫the answer is that it's because it follows
‫the exact same idea as the array reduce method.
‫So just like the reduce method
‫accumulates all array values into one single value,
‫the React reducer accumulates all actions
‫into one single state over time.
‫Okay now, behind the scenes,
‫the dispatch function has access to the reducer
‫because we passed it into the useReducer hook, right?
‫So dispatch is really coordinating this whole thing
‫and also giving the reducer access to the current state.
‫And now to understand this even better,
‫let's compare the mechanism of useReducer
‫with a much simpler useState mechanism.
‫So when we use useState, we get back a setter function
‫and let's just call it setState.
‫And then when we want to update state,
‫we just passed the new updated state value that we want
‫and React will simply update the state
‫which in turn will trigger the re-render.
‫So it's a lot simpler and more straightforward
‫than useReducer, but since useReducer solves the problems
‫that we saw earlier in this lecture,
‫it's a great choice in many situations,
‫even though it's a bit more complicated to set up.
‫But we will talk more about the big advantages of useReducer
‫and also when to use it later in the section.
‫Now, I understand that this whole idea
‫of dispatching actions and writing reducers
‫is super confusing in the beginning.
‫I know because I do remember
‫how confused I was back in the day.
‫And so let me show you now a really helpful analogy
‫that made all this really clear to me
‫when I first learned about this.
‫So imagine that you needed to take $5,000
‫out of your bank account for some reason.
‫Now, since this is a large amount,
‫you can't just do it from an ATM,
‫so you need to go physically to a bank.
‫Now, once you are at the bank,
‫how do you actually get those $5,000?
‫Do you walk straight into the bank's vault,
‫grab the cash, and then go home?
‫Well, I don't think so, right?
‫That's usually not how it works.
‫How it does work is that you go into the bank
‫and there you'll find a person sitting at a desk
‫ready to assist you.
‫Now, when you arrive at the bank,
‫you already know how much cash you want to withdraw
‫and from what account number.
‫And so you walk right to the person
‫and tell them that you would like to withdraw $5,000
‫from account 923577 for example.
‫What happens then is that usually the person
‫will type something into his computer,
‫check if you actually have the cash in your account,
‫and if so, he goes to the bank's vault,
‫and gets the money to finally hand it over to you.
‫It's your money after all, right?
‫But note the big difference between this real version
‫and the previous version of the story
‫where you just grabbed the cash yourself.
‫In this real version, you told the person what to do
‫and how to do it and he then got the money
‫for you on your behalf,
‫and so you didn't take the money directly yourself.
‫And that's a huge difference.
‫So does this maybe start to sound familiar?
‫Well, I hope it does.
‫And so let's now bring this analogy back to useReducer
‫and identify what each of these pieces represents
‫in the useReducer mechanism.
‫And let's start with the most important thing, the state.
‫So what do you think the state is in this analogy?
‫Well, the state is represented by the bank's vault
‫because this is where the relevant data, so the money,
‫is stored and also updated.
‫So the vault is what needs to be updated,
‫and so that's our state.
‫Nice, so with that out of the way,
‫let's think about how the money is taken from the vault.
‫So about how state is actually updated.
‫So starting from the beginning,
‫what do you think the customer going to the bank
‫represents in this analogy?
‫Well, the customer going to the bank
‫and requesting the money is clearly the dispatcher
‫because it is who is requesting the state update, right?
‫And they're doing so by going to the person
‫and requesting to withdraw the $5,000.
‫So what is the reducer here and what is the action?
‫Well, the reducer is going to be
‫the person working at the bank
‫because that's the one who actually makes the update.
‫In this case, it's the one who goes to the vault
‫to get your money.
‫But how does the person know how much money to take
‫and from what account?
‫They know because you told him so
‫exactly in your request message.
‫And so that request message is clearly the action.
‫In this example, the action can be modeled like this.
‫With the action type being withdraw
‫and the payload being the data about the withdrawal
‫that you want to make.
‫So summarizing, you went into the bank
‫with a clear action in mind,
‫you then dispatched that action to the reducer,
‫so to the person working there who took the action,
‫and followed the instructions
‫to take the right amount of money from your account.
‫So from state.
‫he then gave you your money finishing this cycle.
‫So you did not go directly into the vault
‫and took your money.
‫Instead, you had the person, as a middleman,
‫who knows a lot better than you
‫how to perform different actions on the vault.
‫So he knows how to deposit, how to withdraw,
‫how to open and close an account,
‫how to request a loan, and more.
‫And he does all this
‫without you having to worry about the details.
‫So exactly like a reducer function,
‫which also decouples and abstracts
‫all the state updating logic away from you, so that you
‫can have clean and easy to understand components.
‫Okay, so I hope that this now made the relationship
‫between dispatcher, reducer, action, and state crystal clear
‫and you will get plenty of opportunities
‫throughout this section to practice all this.