1 00:00:00,950 --> 00:00:04,490 In the last two videos I've kind of directed away from this last rule right here. 2 00:00:04,490 --> 00:00:05,800 I don't think I can do that anymore. 3 00:00:05,810 --> 00:00:06,980 So let's just get down to it. 4 00:00:06,980 --> 00:00:10,070 Let's talk about what this rule is really talking about. 5 00:00:10,070 --> 00:00:12,460 All right so must not mutate the state argument. 6 00:00:12,590 --> 00:00:13,730 Here's the thing. 7 00:00:13,730 --> 00:00:21,450 This rule is extremely misleading is extremely misleading and possibly even false. 8 00:00:21,500 --> 00:00:26,180 So you might be curious Steven why did you put a misleading or a false rule on this list of rules around 9 00:00:26,180 --> 00:00:27,020 reducers. 10 00:00:27,200 --> 00:00:31,370 Well the reason that I put this rule on here is that you're going to see a tremendous number of blog 11 00:00:31,370 --> 00:00:37,770 posts tutorials and articles even documentation that all give these exact words right here. 12 00:00:37,820 --> 00:00:42,430 All these other people are going to say to you do not mutate that state argument. 13 00:00:42,430 --> 00:00:43,400 But here's the truth. 14 00:00:43,400 --> 00:00:43,860 Let me get it. 15 00:00:43,910 --> 00:00:45,530 I'm going to give you the truth right now. 16 00:00:45,530 --> 00:00:50,560 The truth is you can mutate that state argument all day. 17 00:00:50,900 --> 00:00:56,300 You can add in elements to a you can remove elements you can change elements you can add in properties 18 00:00:56,300 --> 00:01:01,830 to objects you can change properties on objects all on that state's argument. 19 00:01:01,970 --> 00:01:02,720 And you know what. 20 00:01:02,720 --> 00:01:08,270 Redux is never going to give you any error message when you do so. 21 00:01:08,330 --> 00:01:13,310 So all the bad code that we wrote inside this producer right here you can absolutely run this and redux 22 00:01:13,340 --> 00:01:16,120 is not going to throw any error message at you. 23 00:01:16,970 --> 00:01:19,750 But clearly people tell you this rule for a reason. 24 00:01:19,790 --> 00:01:23,880 So why is that why do people say that you must not mutate the state argument. 25 00:01:24,050 --> 00:01:26,620 Well to be honest it really comes down to this right here. 26 00:01:26,720 --> 00:01:32,840 You can mutate that state argument but there is one tiny little corner case in which mutating the state 27 00:01:32,900 --> 00:01:35,400 argument is going to land you in trouble. 28 00:01:35,420 --> 00:01:41,060 There's one tiny little corner case where if you meet that state argument your application is not going 29 00:01:41,060 --> 00:01:47,420 to work the way you expect and to be honest it's a lot easier to tell beginners to just not mutate the 30 00:01:47,420 --> 00:01:53,180 state argument than to tell them about this corner case and help them understand when that corner case 31 00:01:53,240 --> 00:01:54,560 applies. 32 00:01:54,560 --> 00:01:59,000 So in this video I'm going to tell you exactly what that corner case is we're going to get a better 33 00:01:59,030 --> 00:02:04,190 understanding of why people say you must not mutate that state argument. 34 00:02:04,340 --> 00:02:08,790 Right now one thing and do very quickly just to clarify I want to be very clear right now. 35 00:02:08,790 --> 00:02:11,980 You and I are never going to mutate the state argument ever. 36 00:02:12,120 --> 00:02:12,810 You can. 37 00:02:12,810 --> 00:02:13,740 You absolutely can. 38 00:02:13,740 --> 00:02:17,200 And I'm going to show you this corner case and help you really understand this rule. 39 00:02:17,280 --> 00:02:20,520 But we are not going to mutate the state argument ever. 40 00:02:20,610 --> 00:02:25,500 The reason that I am showing you this rule and going so far into detail is that I want to help you understand 41 00:02:25,650 --> 00:02:28,650 the behind the scenes stuff that is going on inside of redux. 42 00:02:28,650 --> 00:02:32,550 But best practice the convention is to not mutate that state argument. 43 00:02:32,640 --> 00:02:34,920 And we are going to stick with that convention. 44 00:02:34,920 --> 00:02:35,330 OK. 45 00:02:35,520 --> 00:02:36,780 So we're not going to take state. 46 00:02:36,780 --> 00:02:39,990 I just want you to better understand what is going on here. 47 00:02:39,990 --> 00:02:40,190 All right. 48 00:02:40,200 --> 00:02:41,480 So let's get to it. 49 00:02:41,670 --> 00:02:47,600 To better understand this rule we're going to take a look at the source code of the redux library itself. 50 00:02:47,640 --> 00:02:52,380 This is a link to the get hub repository that houses all of the source code for redux. 51 00:02:52,410 --> 00:02:53,870 We're going to dive through that source code. 52 00:02:53,880 --> 00:02:58,890 We're going to find one very specific chunk of code and using that knowledge that we just gained around 53 00:02:59,070 --> 00:03:03,630 mutating arrays and objects and doing identity comparisons on Rayson objects. 54 00:03:03,630 --> 00:03:08,730 We're going to get a better idea of exactly what that rule is talking about. 55 00:03:08,730 --> 00:03:13,650 All right so going to copy this link I'm going to pull open a new tab and navigate over there. 56 00:03:15,430 --> 00:03:19,270 So here's the good hub repository with all of the source code for the ducks. 57 00:03:19,270 --> 00:03:22,410 We're going to scroll down a little bit and find the sarcy directory. 58 00:03:22,420 --> 00:03:26,100 So SIRC been inside of this SIRC folder. 59 00:03:26,100 --> 00:03:30,380 You're going to see a couple of very familiar names sirrahs apply middleware yours combined reducers 60 00:03:30,390 --> 00:03:32,390 and here is create store. 61 00:03:32,430 --> 00:03:38,590 We're going to open up the combined reducers thunked file and then inside of combined reducers we're 62 00:03:38,590 --> 00:03:41,570 going to scroll down to the very bottom. 63 00:03:41,580 --> 00:03:46,760 Now as you are looking at this file at some point in time in the future some of the different coding 64 00:03:46,760 --> 00:03:52,080 numbers that you see on the left hand side are a line code lines excuse me are going to be maybe a little 65 00:03:52,080 --> 00:03:53,980 bit changed versus what I'm looking for. 66 00:03:54,090 --> 00:03:59,130 So essentially what we are looking for is something around line 162 we are looking for a variable called 67 00:03:59,190 --> 00:04:01,560 has changed. 68 00:04:01,630 --> 00:04:05,980 So this block of code right here is what we're going to study to really understand what that rule is 69 00:04:05,980 --> 00:04:11,720 talking about this chunk of code see right here is the code that is going to take an action. 70 00:04:11,740 --> 00:04:16,700 Anytime that it gets dispatched and send the action around to all the different reducers inside of your 71 00:04:16,700 --> 00:04:17,810 application. 72 00:04:17,810 --> 00:04:22,320 So in other words every time you dispatch an action this code right here is going to be executed. 73 00:04:22,520 --> 00:04:26,960 So we're going to walk to this code step by step and get a better idea of what happens when you dispatch 74 00:04:27,020 --> 00:04:28,570 an action. 75 00:04:28,740 --> 00:04:29,220 All right. 76 00:04:29,250 --> 00:04:34,020 Notice the first thing that happens is we set up a variable called has changed and equal said equal 77 00:04:34,020 --> 00:04:35,550 to false. 78 00:04:35,550 --> 00:04:37,060 This is a really key variable. 79 00:04:37,080 --> 00:04:39,260 We're going to come back and talk about it in just a little bit. 80 00:04:39,270 --> 00:04:40,170 I just want to point it out. 81 00:04:40,170 --> 00:04:45,410 For right now then on line 164 you'll notice that we enter a for loop. 82 00:04:45,660 --> 00:04:50,150 This for loop is going to iterate over all the different reducers inside of your application. 83 00:04:50,410 --> 00:04:56,650 So at present inside of our index dot J has filed and in the reducers directory We only have one reducer. 84 00:04:56,800 --> 00:05:01,870 But if we had some other reducers inside of here like you know maybe 5 or so something like that that 85 00:05:01,870 --> 00:05:05,740 for a loop is going to iterate over each of these different reduce or functions 86 00:05:08,740 --> 00:05:10,790 then inside the body of the for loop. 87 00:05:10,810 --> 00:05:13,050 Take a look at line 167. 88 00:05:13,150 --> 00:05:14,220 We're looking for a variable right. 89 00:05:14,220 --> 00:05:20,830 You're called previous state for key this variable right here is going to be assigned the last state 90 00:05:20,890 --> 00:05:22,910 value that are reduced or returned. 91 00:05:23,020 --> 00:05:28,000 So remember we just spoke about this every single time that every or gets called The first argument 92 00:05:28,090 --> 00:05:31,930 is going to be the state that returned the last time it had ran. 93 00:05:31,930 --> 00:05:36,910 So essentially this previous state for key is a reference to the previous state value that this particular 94 00:05:36,910 --> 00:05:40,050 reducer that we are iterating over returned. 95 00:05:40,110 --> 00:05:43,630 Then on the next line 168 right here this is the real magic. 96 00:05:43,650 --> 00:05:49,210 This is where we actually invoke your reducer so that reduce or variable right there that is your reducer 97 00:05:49,310 --> 00:05:52,380 that you pass to the combined reducers function. 98 00:05:52,470 --> 00:05:57,660 The first argument is the state that you reduce or return the last time that it ran previous state for 99 00:05:57,660 --> 00:06:01,740 key and then the second argument is the action object. 100 00:06:01,740 --> 00:06:07,530 So your douceur is going to run and then it's going to eventually return some new value some new state 101 00:06:07,530 --> 00:06:11,150 value and that's going to be assigned to next state for key. 102 00:06:11,580 --> 00:06:13,480 So we now have has changed. 103 00:06:13,560 --> 00:06:18,450 We have previous state for Kii which is our last state value and next state for key which is our new 104 00:06:18,450 --> 00:06:19,870 state value. 105 00:06:20,000 --> 00:06:25,430 Immediately after your reduce or runs and assigns that new state value to next save for key redux is 106 00:06:25,430 --> 00:06:30,050 going to check to see if you're reduced or just returned a value of undefined. 107 00:06:30,140 --> 00:06:32,260 That's what this statement right here does. 108 00:06:32,330 --> 00:06:38,060 Remember that was one of our big rules around reducers we had said that a producer can never return 109 00:06:38,090 --> 00:06:39,330 a value of undefined. 110 00:06:39,440 --> 00:06:41,290 And you're seeing that check right here in action. 111 00:06:41,300 --> 00:06:44,250 Redux says OK did they just returned the value undefined. 112 00:06:44,330 --> 00:06:47,920 If they did We're going to throw a new error message. 113 00:06:48,010 --> 00:06:54,520 Now assuming that you get past that check go down to line 174 and here's where things start to get really 114 00:06:54,610 --> 00:06:56,010 really interesting. 115 00:06:56,860 --> 00:06:59,880 So we're going to again look at that has changed value. 116 00:07:01,160 --> 00:07:08,900 Has changed is going to take the value of a direct comparison between next state for me and your previous 117 00:07:08,960 --> 00:07:09,880 state for key. 118 00:07:10,040 --> 00:07:13,460 This is that rule that we're talking about the do not mutate state. 119 00:07:13,520 --> 00:07:18,500 This is what it all comes down to right here to take a look at what this comparison does. 120 00:07:18,500 --> 00:07:21,750 Remember we just spoke about what the not equals equals. 121 00:07:21,800 --> 00:07:28,190 Operator does this checks to see if next state for key and previous state for key are the exact same 122 00:07:28,300 --> 00:07:30,550 array or object in memory. 123 00:07:32,300 --> 00:07:39,620 So if you just returned some array and it is the exact same array in memory that you returned the last 124 00:07:39,620 --> 00:07:46,730 time that this producer ran then has change is going to be a value of false otherwise otherwise if you 125 00:07:46,730 --> 00:07:53,160 reduce or just ran and it just returned a brand new array completely brand new just created inside of 126 00:07:53,160 --> 00:07:53,740 your reducer. 127 00:07:53,750 --> 00:07:59,450 And this is a totally different array than the one that your reducer ran to me returned the last time 128 00:07:59,450 --> 00:08:05,440 it ran then has changed is going to be set equal to true so this has change variable. 129 00:08:05,440 --> 00:08:09,850 Essentially saying has any of the state returned by or reduced or changed. 130 00:08:09,850 --> 00:08:14,320 That is what the name has changed is referring to it as saying we have just dispatch in action. 131 00:08:14,320 --> 00:08:19,500 Has any of the state produced by reducers changed in any way. 132 00:08:19,610 --> 00:08:23,750 So the for loop is going to iterate over all of your reducers and then has changed. 133 00:08:23,780 --> 00:08:26,020 It's going to be either true or false. 134 00:08:26,180 --> 00:08:28,810 Considering all of those different reducers. 135 00:08:28,940 --> 00:08:31,940 Notice how there is only one has changed variable right here. 136 00:08:31,940 --> 00:08:37,370 There is not a separate house change variable for each producer If any different reducer has changed 137 00:08:37,460 --> 00:08:43,670 value or returned a new value a new array or a new object or a different value for an integer or a number 138 00:08:43,670 --> 00:08:46,490 or a string has changed is going to be set equal to true. 139 00:08:46,490 --> 00:08:48,570 So it's kind of a all or nothing deal. 140 00:08:49,550 --> 00:08:53,240 And then after the for loop here's where things get really really interesting. 141 00:08:53,280 --> 00:08:59,630 We then look at the value of how it's changed if has changed is equal to true the result of this entire 142 00:08:59,630 --> 00:09:05,750 function is to return the new state object like the entire new state object that has been assembled 143 00:09:05,750 --> 00:09:13,160 by all of your different reduces otherwise if has changed is equal to false instead return state and 144 00:09:13,160 --> 00:09:18,260 state right here is a reference to all the state that you're reducers returned the last time that they 145 00:09:18,260 --> 00:09:19,800 ran. 146 00:09:19,800 --> 00:09:22,440 So to sum up this code block right here in very simple terms. 147 00:09:22,470 --> 00:09:27,720 Essentially what this does is check to see after running each of your reducers if any reduce or returns 148 00:09:27,930 --> 00:09:33,110 a brand new Array object or value for a number or string. 149 00:09:33,210 --> 00:09:38,200 If they do then redux is going to return the brand new result from all of your reducers. 150 00:09:38,400 --> 00:09:43,280 Otherwise if you're reducers returned no new value it's going to return the old states where the old 151 00:09:43,290 --> 00:09:45,600 result from each of your reducers. 152 00:09:45,600 --> 00:09:47,190 Now why is that relevant. 153 00:09:47,190 --> 00:09:53,670 The reason this is relevant is that if redux returns the old state value right here then redux is not 154 00:09:53,670 --> 00:09:58,670 going to notify the rest of your application that any of your data has changed. 155 00:10:00,270 --> 00:10:02,170 If you do have a new state. 156 00:10:02,220 --> 00:10:06,210 If you have changed something from one of your producers and you instead return next state right here 157 00:10:06,390 --> 00:10:08,160 redux is going to look at that object. 158 00:10:08,160 --> 00:10:12,750 It's going to say oh we just got some new states some new state just came out of all of our different 159 00:10:12,750 --> 00:10:18,210 reducers and it's then going to notify the rest of your application including your re-act application 160 00:10:18,750 --> 00:10:25,930 that you have a new state available and that is going to cause your re-act application to re render. 161 00:10:25,930 --> 00:10:33,340 So in summary the reason we care so much about saying that you must not mutate at state argument is 162 00:10:33,340 --> 00:10:35,820 not because you can't mutate the state argument. 163 00:10:35,830 --> 00:10:37,060 That's not the case. 164 00:10:37,060 --> 00:10:43,710 The reason we say this is that if you accidentally return the same value that is pumped into your reducer 165 00:10:43,720 --> 00:10:49,930 like even if you change it even if we modify this thing right here if we eventually say return state 166 00:10:49,960 --> 00:10:54,740 at the very bottom and it's still the same object or the same array be it modified or not. 167 00:10:54,820 --> 00:10:59,430 Redux is going to say oh no difference here is the same object or array in memory. 168 00:10:59,440 --> 00:11:00,450 Nothing has changed. 169 00:11:00,520 --> 00:11:04,460 And so we have done absolutely no updates to any data inside of our application. 170 00:11:04,540 --> 00:11:07,140 And the re-act up does not need to be rendered itself. 171 00:11:07,290 --> 00:11:11,370 And so you will never see any updated content appear on the screen. 172 00:11:11,500 --> 00:11:13,490 That is what is actually going on here. 173 00:11:13,630 --> 00:11:17,740 And that is what this rule right here is really trying to convey. 174 00:11:17,830 --> 00:11:24,900 This rule is really trying to tell you if you return the state argument right here making changes to 175 00:11:24,900 --> 00:11:26,210 it or not making changes to it. 176 00:11:26,220 --> 00:11:31,320 It doesn't matter if you return the same value at the very bottom then no update will be made to your 177 00:11:31,320 --> 00:11:33,060 application and that's it. 178 00:11:33,060 --> 00:11:36,540 That is what people are trying to convey with this real right here. 179 00:11:36,570 --> 00:11:40,410 That is why people say do not mutate these state arguments. 180 00:11:40,530 --> 00:11:45,220 Now as you might imagine it's a lot easier to just tell people do not mutate the state argument than 181 00:11:45,240 --> 00:11:48,900 to go through the description or the entire process that I just gave you. 182 00:11:48,900 --> 00:11:51,640 So that's why it's a lot easier for when you're first learning redux. 183 00:11:51,690 --> 00:11:56,280 Just understand don't mutate the state argument than to actually understand all the behind the scenes 184 00:11:56,280 --> 00:11:57,270 stuff that's going on. 185 00:11:58,570 --> 00:11:59,050 OK. 186 00:11:59,250 --> 00:11:59,900 So that's it. 187 00:11:59,940 --> 00:12:01,680 That's rule number for around reducers. 188 00:12:01,680 --> 00:12:04,060 We've now gone through a whole four rules right here. 189 00:12:04,200 --> 00:12:05,330 Now to take a quick pause. 190 00:12:05,370 --> 00:12:10,080 When we come back the next section I'm going to tell you how we are going to generally handle arrays 191 00:12:10,110 --> 00:12:15,540 and objects inside of reducer so we can handle this rule appropriately and make sure that if we do want 192 00:12:15,540 --> 00:12:21,540 to make a change to the state argument we don't do so in a way that is friendly and familiar to redux. 193 00:12:21,570 --> 00:12:23,710 So quick pause and I'll see you in just a minute.