1 00:00:01,480 --> 00:00:04,560 We've now seen some really weird behavior in this very small example. 2 00:00:04,570 --> 00:00:09,180 So let's not take a look at a quick diagram to understand exactly what is going on inside of here. 3 00:00:09,400 --> 00:00:10,340 So quick diagram. 4 00:00:10,360 --> 00:00:11,390 Here we go. 5 00:00:11,440 --> 00:00:14,320 This is a diagram of what's going on inside that code pen example. 6 00:00:14,320 --> 00:00:18,900 During the very first time that the app component is rendered to the screen so the very first time it 7 00:00:18,900 --> 00:00:23,350 gets rendered we're calling counter or we're setting up a counter piece of states in initializing it 8 00:00:23,350 --> 00:00:24,740 to zero. 9 00:00:24,760 --> 00:00:27,220 We then call that use effect function. 10 00:00:27,220 --> 00:00:32,500 Inside there we set up these set interval call and it has a direct reference to that counter variable 11 00:00:32,890 --> 00:00:33,920 like so. 12 00:00:34,110 --> 00:00:36,940 So we can kind of imagine that inside of sound set interval. 13 00:00:37,030 --> 00:00:41,070 The counter references that counter variable that currently has a value of zero. 14 00:00:41,080 --> 00:00:41,410 Right. 15 00:00:41,410 --> 00:00:42,850 Simple enough. 16 00:00:42,900 --> 00:00:48,390 So what really goes on during any time we press the increment or decrement button. 17 00:00:48,390 --> 00:00:53,550 Well as usual because we're pressing increment or decrement right there we call set counter which remember 18 00:00:53,550 --> 00:00:58,230 is going to rerun our component automatically during that re render. 19 00:00:58,350 --> 00:01:03,450 We are not going to run the use effect function because we put in that argument of an empty array as 20 00:01:03,450 --> 00:01:11,180 the second argument so we can kind of imagine that we then get that second render so going to duplicate 21 00:01:11,180 --> 00:01:12,800 that box moved over here. 22 00:01:12,810 --> 00:01:19,910 Call it second time render during that second render the value of counter might go up to is 1 or negative 23 00:01:19,910 --> 00:01:22,280 1 depending on what button gets pressed. 24 00:01:22,310 --> 00:01:25,080 So the value of counter definitely is now different. 25 00:01:25,160 --> 00:01:31,100 However during the second render we do not rerun the use effect function a second time that doesn't 26 00:01:31,100 --> 00:01:38,410 run instead because we put in that empty array use effect does not get invoked. 27 00:01:38,420 --> 00:01:39,980 Now why is that relevant. 28 00:01:39,980 --> 00:01:45,500 Well they say the set interval that we set up during the first time render is still running in the background 29 00:01:45,950 --> 00:01:51,860 and the core issue here is that that set interval function still has a reference to that old version 30 00:01:51,920 --> 00:01:53,520 of the counter variable. 31 00:01:53,600 --> 00:01:58,440 There's nothing inside of here that somehow tells that set interval hey the value of counter changed. 32 00:01:58,490 --> 00:02:05,570 Instead we are working with a completely new variable called counter the first time render has one version 33 00:02:05,570 --> 00:02:06,990 of the counter variable. 34 00:02:07,130 --> 00:02:12,980 So that is like one variable sitting in memory and our set interval is referencing that variable in 35 00:02:12,980 --> 00:02:14,330 memory. 36 00:02:14,540 --> 00:02:20,000 The second time we run our component a completely new counter variable is created in memory. 37 00:02:20,000 --> 00:02:24,230 And this has a completely different value than the original account or variable that was created over 38 00:02:24,230 --> 00:02:25,150 here. 39 00:02:25,220 --> 00:02:28,970 So set interval still has a reference to the old value of counter. 40 00:02:29,210 --> 00:02:34,340 And like I said there's nothing to somehow tell it to stop looking at that old value and start looking 41 00:02:34,340 --> 00:02:35,580 at the new value instead. 42 00:02:35,750 --> 00:02:40,760 We don't have any reasonable way of telling the set interval to say hey make sure you go and use this 43 00:02:40,760 --> 00:02:46,930 new variable in memory as opposed to the old one so that's essentially what's going on every single 44 00:02:46,930 --> 00:02:50,180 time we update our component or render it at all. 45 00:02:50,200 --> 00:02:55,330 There's nothing to go on or no mechanism to somehow reach in to set interval and tell it to use the 46 00:02:55,330 --> 00:03:01,210 new value of counter forever it's going to be referencing that original value. 47 00:03:01,290 --> 00:03:03,100 So how can we fix this. 48 00:03:03,120 --> 00:03:09,170 Well one way we could fix it back over encode ban would be to remove that empty array right there. 49 00:03:09,210 --> 00:03:13,590 So if we removed that empty array it means that we are now going to call that inner function. 50 00:03:13,680 --> 00:03:18,120 So that one right there every single time we re render our component. 51 00:03:18,120 --> 00:03:24,100 So if I remove that empty Ray and then click on increment will now see a new interval console I'd write 52 00:03:24,100 --> 00:03:26,860 your new console log for that value of counter. 53 00:03:26,860 --> 00:03:30,190 You'll notice that we're still getting some values of zero console logged out as well. 54 00:03:30,190 --> 00:03:35,740 That's because remember now every single time that we re render app we're setting up a new interval. 55 00:03:35,740 --> 00:03:40,030 So we're going to always be seeing a console log of every different version of counter that we ever 56 00:03:40,030 --> 00:03:41,260 encountered. 57 00:03:41,260 --> 00:03:46,270 So if I now click on increment a couple of times we're essentially setting up a bunch of different intervals 58 00:03:46,540 --> 00:03:50,080 each of which have a reference to a different value of counter. 59 00:03:50,110 --> 00:03:54,340 So now inside my console I see everything from zero all the way to nine being console logged one by 60 00:03:54,340 --> 00:03:55,750 one. 61 00:03:55,770 --> 00:03:59,570 So this is essentially the same issue that's going on inside of our project right now. 62 00:03:59,760 --> 00:04:03,840 But understanding exactly what's going on is just all a bit more complicated because we are working 63 00:04:03,840 --> 00:04:10,470 with a lot more data than inside of this very simple example so let's now take this knowledge and apply 64 00:04:10,470 --> 00:04:17,270 it to our application and understand why our use effect call is not quite working out as expected so 65 00:04:17,270 --> 00:04:18,090 back inside my code. 66 00:04:18,100 --> 00:04:21,170 Ed I want to remind you of two things very quickly. 67 00:04:21,170 --> 00:04:25,110 First off inside a track create screen right here. 68 00:04:25,130 --> 00:04:30,970 We put together this callback function that we pass in to use location inside of that callback function. 69 00:04:30,980 --> 00:04:34,710 We have a reference to this variable of state DOT recording. 70 00:04:34,730 --> 00:04:38,880 So just keep that in mind for a second then inside of use location. 71 00:04:38,880 --> 00:04:44,670 So here's the hook we received that callback inside of use effect. 72 00:04:44,910 --> 00:04:51,370 We call start watching that runs our start watching function right here and inside of start watching. 73 00:04:51,410 --> 00:04:55,430 We have a reference to that same callback function that we just passed in. 74 00:04:55,590 --> 00:04:56,830 So what those two things in mind. 75 00:04:56,850 --> 00:05:02,620 Let's not take a look at a diagram and understand exactly what's going wrong inside of use location. 76 00:05:02,700 --> 00:05:03,030 All right. 77 00:05:03,030 --> 00:05:08,030 So we've got a similar diagram here but give me just a little bit more complicated so inside of track 78 00:05:08,030 --> 00:05:09,210 create screen. 79 00:05:09,320 --> 00:05:14,360 I want you to imagine what occurs during the very first render of our application the very first render 80 00:05:14,630 --> 00:05:19,400 we're going to have a default value of recording set to false because remember by default our recording 81 00:05:19,400 --> 00:05:25,350 values false which means we are not recording a track at that point in time inside of track rate screen 82 00:05:25,590 --> 00:05:28,970 we assemble that callback function inside that callback function. 83 00:05:28,980 --> 00:05:31,790 We have a direct reference to that recording variable. 84 00:05:32,160 --> 00:05:34,800 So that's inside of a track create screen right there. 85 00:05:34,800 --> 00:05:40,150 State DOT recording a direct reference to that variable so we can imagine that that green box right 86 00:05:40,150 --> 00:05:44,130 there is referring to that copy of the recording variable. 87 00:05:44,140 --> 00:05:48,370 Now I know that technically we're referring to state DOT recording but the idea is the same. 88 00:05:48,370 --> 00:05:53,130 Essentially we've got some a variable in memory and its current value is false. 89 00:05:53,200 --> 00:05:57,400 We then take that callback and pass it into the use location hook. 90 00:05:57,400 --> 00:06:01,890 So during the first call of use location we run that use effect hook. 91 00:06:01,900 --> 00:06:02,410 Right. 92 00:06:02,410 --> 00:06:08,930 That's use effect right down here inside of U.S. fact we call start watching. 93 00:06:09,160 --> 00:06:14,980 So we call start watching so then start watching calls or runs excuse me and instead of start watching 94 00:06:14,980 --> 00:06:16,620 once we go through all that permission stuff. 95 00:06:16,630 --> 00:06:21,710 And once we start watching the user's location we then eventually run our callback function. 96 00:06:21,940 --> 00:06:27,690 So that orange callback box right there that's essentially that callback function right there. 97 00:06:27,700 --> 00:06:33,110 So we are running that callback function and inside that callback function we have a direct reference 98 00:06:33,110 --> 00:06:40,020 to that recording value variable in its current value is false so same thing that we are going through 99 00:06:40,020 --> 00:06:42,280 inside of code pen right now. 100 00:06:42,300 --> 00:06:47,460 So now we want you to think about what happens whenever we press that start recording button on our 101 00:06:47,460 --> 00:06:52,800 track create screen or inside the track form whenever we click start recording right there what goes 102 00:06:52,800 --> 00:06:53,640 on. 103 00:06:53,910 --> 00:06:59,060 Well we essentially are going to re render our track create screen a second time. 104 00:06:59,070 --> 00:07:05,260 So going to duplicate that box over here so we're going to get I've kind of already made that diagram 105 00:07:05,270 --> 00:07:06,750 we delete this one right here. 106 00:07:06,750 --> 00:07:07,980 There we go that's better. 107 00:07:08,020 --> 00:07:12,960 So we are going to run track rate screen a second time at this point. 108 00:07:12,970 --> 00:07:16,160 Recording is now going to be equal to true. 109 00:07:16,190 --> 00:07:18,770 We then recreate our callback function. 110 00:07:18,770 --> 00:07:21,510 So the callback function does successfully get recreated. 111 00:07:21,560 --> 00:07:21,830 Right. 112 00:07:21,830 --> 00:07:28,780 So we are creating a second version of it back inside of track create screen right here we create that 113 00:07:28,780 --> 00:07:30,610 function a second time. 114 00:07:30,610 --> 00:07:35,860 And now that function does have the correct reference to the recording variable it now says OK recording 115 00:07:35,920 --> 00:07:37,990 is 100 percent set to true. 116 00:07:38,590 --> 00:07:45,140 However what happens inside of use location so we can imagine that during that second re render we call 117 00:07:45,370 --> 00:07:48,840 use location a second time. 118 00:07:48,850 --> 00:07:49,870 Now here's the issue. 119 00:07:49,900 --> 00:07:53,980 The second time use effect does not get invoked again. 120 00:07:53,980 --> 00:07:55,510 We don't call it a second time. 121 00:07:55,570 --> 00:08:02,290 The only time that we ever call U.S. fact again back over here inside of your location is when the value 122 00:08:02,320 --> 00:08:07,840 of should track changes when a user taps on that state DOT or that start recording button we change 123 00:08:07,840 --> 00:08:11,650 the recording variable not should track or anything like that. 124 00:08:11,680 --> 00:08:16,940 So the second time that we run use location this function right here doesn't run. 125 00:08:17,050 --> 00:08:20,140 It doesn't get invoked because that does not run. 126 00:08:20,140 --> 00:08:23,610 That means that start watching doesn't get ran. 127 00:08:23,620 --> 00:08:27,500 So start watching doesn't get ran and nothing inside of here. 128 00:08:27,490 --> 00:08:28,300 Nothing inside of you. 129 00:08:28,360 --> 00:08:34,300 Use location somehow reaches back over to this previous version of everything we executed and tells 130 00:08:34,360 --> 00:08:39,270 that old version of start watching to start using the new callback that was passed in. 131 00:08:39,370 --> 00:08:42,790 So it's the very same scenario that we are in inside of code Penn. 132 00:08:42,790 --> 00:08:46,960 I know it's kind of different because I had said previously hey this like we're referencing this old 133 00:08:46,960 --> 00:08:48,700 value of recording or stuff like that. 134 00:08:48,700 --> 00:08:49,960 We essentially still are. 135 00:08:50,050 --> 00:08:53,790 I know the callback is getting a reference to the latest version that we're creating over here. 136 00:08:53,800 --> 00:08:59,260 The issue this time around is that we don't ever get a reference to that callback into art start watching 137 00:08:59,260 --> 00:09:00,270 function. 138 00:09:00,340 --> 00:09:06,430 So the copy of Start watching that is currently running the copy of that watch location async that we're 139 00:09:06,430 --> 00:09:11,650 running still has a reference to the old callback and the old callback still thinks that recording is 140 00:09:11,650 --> 00:09:14,960 equal to False so why is that relevant. 141 00:09:14,960 --> 00:09:22,270 Well remember that recording variable controls whether or not we are passing in back inside of art location 142 00:09:22,270 --> 00:09:25,370 context here's add location right here. 143 00:09:25,420 --> 00:09:31,270 That recording variable gets passed into add location and it is solely that recording variable that 144 00:09:31,270 --> 00:09:37,420 controls whether or not we add in this most recent location to our array of locations. 145 00:09:37,420 --> 00:09:43,210 So inside of your recording is always going to be equal to False no matter what even if inside of our 146 00:09:43,210 --> 00:09:48,490 state object we somehow update the value of recording whenever we call add location recording will always 147 00:09:48,490 --> 00:09:53,680 be false which means we're never going to dispatch that action and we can very easily test this out 148 00:09:54,220 --> 00:10:00,080 inside of here right after dispatch we can put in a console log of recording like so if I now go back 149 00:10:00,080 --> 00:10:06,190 over and hit start recording we're definitely calling at location right now. 150 00:10:06,190 --> 00:10:10,850 Without a doubt because remember ad location is in charge of updating that little circle. 151 00:10:10,930 --> 00:10:14,940 So because that circle is moving we know that ad location is being invoked. 152 00:10:15,010 --> 00:10:20,640 So if we go back over to our terminal we're going to see that we get a bunch of false statements right 153 00:10:20,640 --> 00:10:20,950 here. 154 00:10:20,970 --> 00:10:24,380 So false means state DOT recording is set to false. 155 00:10:24,510 --> 00:10:29,100 So it's hundred percent false that means we're never going to dispatch that action to add our location 156 00:10:29,100 --> 00:10:35,450 to the array of locations and therefore our array of locations always has a length of zero as a little 157 00:10:35,450 --> 00:10:39,920 bit more debugging that you might want to try out here just to look kind of like verify what's going 158 00:10:39,920 --> 00:10:40,350 on. 159 00:10:40,370 --> 00:10:46,310 We could also go back over the track create screen inside of track rate screen right above where we 160 00:10:46,310 --> 00:10:52,820 call use location we can put in a console log of state DOT recording and write about before that value 161 00:10:52,830 --> 00:10:56,150 I'll put in something that says like outside. 162 00:10:56,150 --> 00:11:02,160 So this is the value of state DOT recording outside our callback and output as similar council log and 163 00:11:02,160 --> 00:11:03,880 say inside. 164 00:11:03,890 --> 00:11:07,440 So take a look at this now we've got state DOT recording and state DOT recording. 165 00:11:07,440 --> 00:11:14,050 Let's now save this and see what happens it's all save it go back over and check create hit start recording 166 00:11:15,090 --> 00:11:20,670 go back over my terminal and take a look at that we've now got an inside of false and an outside of 167 00:11:20,670 --> 00:11:27,390 true so outside that callback recording is set to true inside of it it's set to false and like we just 168 00:11:27,390 --> 00:11:33,530 discussed that's a hundred percent because our start watching function is still calling the original 169 00:11:33,530 --> 00:11:39,740 callback that we put together and passed down into use location during the first render a second render 170 00:11:39,740 --> 00:11:44,630 occurred and we've got a new callback being assembled and we're passing that callback into use location 171 00:11:44,660 --> 00:11:47,390 but it just never gets used. 172 00:11:47,420 --> 00:11:53,780 So start watching is always calling that first version of our callback which always has a recording 173 00:11:53,780 --> 00:11:55,650 flag a false. 174 00:11:55,650 --> 00:11:57,040 So that's what's going on here. 175 00:11:57,110 --> 00:12:01,030 And as you can imagine this is a super nasty bug. 176 00:12:01,040 --> 00:12:04,240 This is like the worst thing you can possibly encounter. 177 00:12:04,280 --> 00:12:08,210 So this is without a doubt in remove those council logs by the way without a doubt this is like one 178 00:12:08,210 --> 00:12:10,550 the worse things around making use of hooks. 179 00:12:10,550 --> 00:12:15,660 It is incredibly easy to fall into traps like this specifically around use effect. 180 00:12:15,770 --> 00:12:19,240 And it's really hard to debug and figure out what's going on. 181 00:12:19,490 --> 00:12:24,860 So clearly we would love to have some kind of strategy to mitigate this and try to figure out some way 182 00:12:24,860 --> 00:12:27,660 to not run into issues like this in the future. 183 00:12:27,660 --> 00:12:31,220 So let's take a pause right here when we come back the next video we're going to figure out how we can 184 00:12:31,220 --> 00:12:33,310 solve the issue that we're currently running into. 185 00:12:33,370 --> 00:12:37,130 And we're also going to discuss a couple of ways that we can kind of avoid running into issues like 186 00:12:37,130 --> 00:12:41,590 this at some point in the future as well so quick pause I'll see you in just a minute.