In the last two videos I've kind of directed away from this last rule right here.
I don't think I can do that anymore.
So let's just get down to it.
Let's talk about what this rule is really talking about.
All right so must not mutate the state argument.
Here's the thing.
This rule is extremely misleading is extremely misleading and possibly even false.
So you might be curious Steven why did you put a misleading or a false rule on this list of rules around
reducers.
Well the reason that I put this rule on here is that you're going to see a tremendous number of blog
posts tutorials and articles even documentation that all give these exact words right here.
All these other people are going to say to you do not mutate that state argument.
But here's the truth.
Let me get it.
I'm going to give you the truth right now.
The truth is you can mutate that state argument all day.
You can add in elements to a you can remove elements you can change elements you can add in properties
to objects you can change properties on objects all on that state's argument.
And you know what.
Redux is never going to give you any error message when you do so.
So all the bad code that we wrote inside this producer right here you can absolutely run this and redux
is not going to throw any error message at you.
But clearly people tell you this rule for a reason.
So why is that why do people say that you must not mutate the state argument.
Well to be honest it really comes down to this right here.
You can mutate that state argument but there is one tiny little corner case in which mutating the state
argument is going to land you in trouble.
There's one tiny little corner case where if you meet that state argument your application is not going
to work the way you expect and to be honest it's a lot easier to tell beginners to just not mutate the
state argument than to tell them about this corner case and help them understand when that corner case
applies.
So in this video I'm going to tell you exactly what that corner case is we're going to get a better
understanding of why people say you must not mutate that state argument.
Right now one thing and do very quickly just to clarify I want to be very clear right now.
You and I are never going to mutate the state argument ever.
You can.
You absolutely can.
And I'm going to show you this corner case and help you really understand this rule.
But we are not going to mutate the state argument ever.
The reason that I am showing you this rule and going so far into detail is that I want to help you understand
the behind the scenes stuff that is going on inside of redux.
But best practice the convention is to not mutate that state argument.
And we are going to stick with that convention.
OK.
So we're not going to take state.
I just want you to better understand what is going on here.
All right.
So let's get to it.
To better understand this rule we're going to take a look at the source code of the redux library itself.
This is a link to the get hub repository that houses all of the source code for redux.
We're going to dive through that source code.
We're going to find one very specific chunk of code and using that knowledge that we just gained around
mutating arrays and objects and doing identity comparisons on Rayson objects.
We're going to get a better idea of exactly what that rule is talking about.
All right so going to copy this link I'm going to pull open a new tab and navigate over there.
So here's the good hub repository with all of the source code for the ducks.
We're going to scroll down a little bit and find the sarcy directory.
So SIRC been inside of this SIRC folder.
You're going to see a couple of very familiar names sirrahs apply middleware yours combined reducers
and here is create store.
We're going to open up the combined reducers thunked file and then inside of combined reducers we're
going to scroll down to the very bottom.
Now as you are looking at this file at some point in time in the future some of the different coding
numbers that you see on the left hand side are a line code lines excuse me are going to be maybe a little
bit changed versus what I'm looking for.
So essentially what we are looking for is something around line 162 we are looking for a variable called
has changed.
So this block of code right here is what we're going to study to really understand what that rule is
talking about this chunk of code see right here is the code that is going to take an action.
Anytime that it gets dispatched and send the action around to all the different reducers inside of your
application.
So in other words every time you dispatch an action this code right here is going to be executed.
So we're going to walk to this code step by step and get a better idea of what happens when you dispatch
an action.
All right.
Notice the first thing that happens is we set up a variable called has changed and equal said equal
to false.
This is a really key variable.
We're going to come back and talk about it in just a little bit.
I just want to point it out.
For right now then on line 164 you'll notice that we enter a for loop.
This for loop is going to iterate over all the different reducers inside of your application.
So at present inside of our index dot J has filed and in the reducers directory We only have one reducer.
But if we had some other reducers inside of here like you know maybe 5 or so something like that that
for a loop is going to iterate over each of these different reduce or functions
then inside the body of the for loop.
Take a look at line 167.
We're looking for a variable right.
You're called previous state for key this variable right here is going to be assigned the last state
value that are reduced or returned.
So remember we just spoke about this every single time that every or gets called The first argument
is going to be the state that returned the last time it had ran.
So essentially this previous state for key is a reference to the previous state value that this particular
reducer that we are iterating over returned.
Then on the next line 168 right here this is the real magic.
This is where we actually invoke your reducer so that reduce or variable right there that is your reducer
that you pass to the combined reducers function.
The first argument is the state that you reduce or return the last time that it ran previous state for
key and then the second argument is the action object.
So your douceur is going to run and then it's going to eventually return some new value some new state
value and that's going to be assigned to next state for key.
So we now have has changed.
We have previous state for Kii which is our last state value and next state for key which is our new
state value.
Immediately after your reduce or runs and assigns that new state value to next save for key redux is
going to check to see if you're reduced or just returned a value of undefined.
That's what this statement right here does.
Remember that was one of our big rules around reducers we had said that a producer can never return
a value of undefined.
And you're seeing that check right here in action.
Redux says OK did they just returned the value undefined.
If they did We're going to throw a new error message.
Now assuming that you get past that check go down to line 174 and here's where things start to get really
really interesting.
So we're going to again look at that has changed value.
Has changed is going to take the value of a direct comparison between next state for me and your previous
state for key.
This is that rule that we're talking about the do not mutate state.
This is what it all comes down to right here to take a look at what this comparison does.
Remember we just spoke about what the not equals equals.
Operator does this checks to see if next state for key and previous state for key are the exact same
array or object in memory.
So if you just returned some array and it is the exact same array in memory that you returned the last
time that this producer ran then has change is going to be a value of false otherwise otherwise if you
reduce or just ran and it just returned a brand new array completely brand new just created inside of
your reducer.
And this is a totally different array than the one that your reducer ran to me returned the last time
it ran then has changed is going to be set equal to true so this has change variable.
Essentially saying has any of the state returned by or reduced or changed.
That is what the name has changed is referring to it as saying we have just dispatch in action.
Has any of the state produced by reducers changed in any way.
So the for loop is going to iterate over all of your reducers and then has changed.
It's going to be either true or false.
Considering all of those different reducers.
Notice how there is only one has changed variable right here.
There is not a separate house change variable for each producer If any different reducer has changed
value or returned a new value a new array or a new object or a different value for an integer or a number
or a string has changed is going to be set equal to true.
So it's kind of a all or nothing deal.
And then after the for loop here's where things get really really interesting.
We then look at the value of how it's changed if has changed is equal to true the result of this entire
function is to return the new state object like the entire new state object that has been assembled
by all of your different reduces otherwise if has changed is equal to false instead return state and
state right here is a reference to all the state that you're reducers returned the last time that they
ran.
So to sum up this code block right here in very simple terms.
Essentially what this does is check to see after running each of your reducers if any reduce or returns
a brand new Array object or value for a number or string.
If they do then redux is going to return the brand new result from all of your reducers.
Otherwise if you're reducers returned no new value it's going to return the old states where the old
result from each of your reducers.
Now why is that relevant.
The reason this is relevant is that if redux returns the old state value right here then redux is not
going to notify the rest of your application that any of your data has changed.
If you do have a new state.
If you have changed something from one of your producers and you instead return next state right here
redux is going to look at that object.
It's going to say oh we just got some new states some new state just came out of all of our different
reducers and it's then going to notify the rest of your application including your re-act application
that you have a new state available and that is going to cause your re-act application to re render.
So in summary the reason we care so much about saying that you must not mutate at state argument is
not because you can't mutate the state argument.
That's not the case.
The reason we say this is that if you accidentally return the same value that is pumped into your reducer
like even if you change it even if we modify this thing right here if we eventually say return state
at the very bottom and it's still the same object or the same array be it modified or not.
Redux is going to say oh no difference here is the same object or array in memory.
Nothing has changed.
And so we have done absolutely no updates to any data inside of our application.
And the re-act up does not need to be rendered itself.
And so you will never see any updated content appear on the screen.
That is what is actually going on here.
And that is what this rule right here is really trying to convey.
This rule is really trying to tell you if you return the state argument right here making changes to
it or not making changes to it.
It doesn't matter if you return the same value at the very bottom then no update will be made to your
application and that's it.
That is what people are trying to convey with this real right here.
That is why people say do not mutate these state arguments.
Now as you might imagine it's a lot easier to just tell people do not mutate the state argument than
to go through the description or the entire process that I just gave you.
So that's why it's a lot easier for when you're first learning redux.
Just understand don't mutate the state argument than to actually understand all the behind the scenes
stuff that's going on.
OK.
So that's it.
That's rule number for around reducers.
We've now gone through a whole four rules right here.
Now to take a quick pause.
When we come back the next section I'm going to tell you how we are going to generally handle arrays
and objects inside of reducer so we can handle this rule appropriately and make sure that if we do want
to make a change to the state argument we don't do so in a way that is friendly and familiar to redux.
So quick pause and I'll see you in just a minute.