﻿1
00:00:01,170 --> 00:00:03,840
‫In this video, we're gonna play a sound

2
00:00:03,840 --> 00:00:06,810
‫whenever the duration state changes.

3
00:00:06,810 --> 00:00:10,620
‫And this will bring up all kinds of interesting issues

4
00:00:10,620 --> 00:00:12,150
‫that we are gonna solve using

5
00:00:12,150 --> 00:00:14,550
‫the strategies that we have learned

6
00:00:14,550 --> 00:00:18,353
‫in the advanced useEffect lecture earlier.

7
00:00:18,353 --> 00:00:21,720
‫And I already created this function here

8
00:00:21,720 --> 00:00:26,340
‫to play a certain sound and I think it's pretty interesting.

9
00:00:26,340 --> 00:00:31,340
‫So what we have to do is to first import a sound file.

10
00:00:31,391 --> 00:00:36,118
‫So like this one that is here in the source folder.

11
00:00:36,118 --> 00:00:41,118
‫So we import that then store it into some variable,

12
00:00:41,220 --> 00:00:43,050
‫and then we can use that using

13
00:00:43,050 --> 00:00:46,110
‫the audio API from the browser.

14
00:00:46,110 --> 00:00:49,530
‫So this is here just a browser feature.

15
00:00:49,530 --> 00:00:53,850
‫So this then creates a new audio, which I just called sound.

16
00:00:53,850 --> 00:00:56,883
‫And then on that we can call the play method.

17
00:00:57,993 --> 00:01:01,080
‫And so now let's use this function

18
00:01:01,080 --> 00:01:03,600
‫in order to play this sound

19
00:01:03,600 --> 00:01:06,660
‫each time that the duration updates.

20
00:01:06,660 --> 00:01:09,690
‫So where does that actually happen?

21
00:01:09,690 --> 00:01:12,570
‫So where does the duration update?

22
00:01:12,570 --> 00:01:14,190
‫Well, easy enough.

23
00:01:14,190 --> 00:01:18,300
‫Here in these two handler functions and in this effect.

24
00:01:18,300 --> 00:01:22,484
‫And so let's just play or actually call

25
00:01:22,484 --> 00:01:27,017
‫that function in all those places.

26
00:01:27,017 --> 00:01:31,264
‫So here and here.

27
00:01:31,264 --> 00:01:33,630
‫So in the two event handlers

28
00:01:33,630 --> 00:01:36,093
‫and let's already test if this works.

29
00:01:37,200 --> 00:01:39,330
‫And yeah, I can very clearly hear

30
00:01:39,330 --> 00:01:41,520
‫that sound in my headphones.

31
00:01:41,520 --> 00:01:44,520
‫So it's not in the video because of my headphones,

32
00:01:44,520 --> 00:01:47,490
‫but you should probably also hear it.

33
00:01:47,490 --> 00:01:49,680
‫Now if you do not want that sound

34
00:01:49,680 --> 00:01:53,160
‫maybe because you need to be in silence or something,

35
00:01:53,160 --> 00:01:56,400
‫then you have this icon right here.

36
00:01:56,400 --> 00:01:59,886
‫So this is coming from the toggle sounds component.

37
00:01:59,886 --> 00:02:01,650
‫And so when you click here,

38
00:02:01,650 --> 00:02:05,100
‫it will set the allowSound state to false.

39
00:02:05,100 --> 00:02:09,228
‫And so then in this case, the sound is not played.

40
00:02:09,228 --> 00:02:11,973
‫So then it goes just back to normal.

41
00:02:13,094 --> 00:02:17,430
‫But here for the sake of this exercise,

42
00:02:17,430 --> 00:02:21,093
‫let's leave it on and see that it works just fine.

43
00:02:22,390 --> 00:02:25,830
‫But of course, as we change the duration here

44
00:02:25,830 --> 00:02:28,170
‫that will not yet play the sound.

45
00:02:28,170 --> 00:02:31,473
‫And so let's also place that here.

46
00:02:35,679 --> 00:02:40,679
‫But now this play sound is actually a reactive value

47
00:02:40,740 --> 00:02:44,400
‫because it uses another reactive value.

48
00:02:44,400 --> 00:02:49,400
‫So this allows sound prop, so it is actually a prop,

49
00:02:49,530 --> 00:02:54,530
‫but we see that it is a prop that is actually state.

50
00:02:55,230 --> 00:02:58,680
‫So that allowSound prop is a state variable

51
00:02:58,680 --> 00:03:01,170
‫and therefore it is a reactive value.

52
00:03:01,170 --> 00:03:04,560
‫And so this function is then also a reactive value

53
00:03:04,560 --> 00:03:06,993
‫and then we need to place it right here.

54
00:03:08,190 --> 00:03:11,880
‫So playSound like this.

55
00:03:11,880 --> 00:03:14,550
‫Now here since we are using

56
00:03:14,550 --> 00:03:19,550
‫not a normal function declaration, function expression,

57
00:03:20,010 --> 00:03:21,843
‫we need to place it here before.

58
00:03:22,860 --> 00:03:25,830
‫And so now it is back to working.

59
00:03:25,830 --> 00:03:29,370
‫Now notice how here in the console we get these issues,

60
00:03:29,370 --> 00:03:32,730
‫which tells us that a sound cannot be played

61
00:03:32,730 --> 00:03:35,970
‫before the user interacts with the document.

62
00:03:35,970 --> 00:03:39,150
‫So the user first need to click or really do

63
00:03:39,150 --> 00:03:42,870
‫something here before the first sound can be played.

64
00:03:42,870 --> 00:03:46,743
‫But let's just ignore this issue here in the situation.

65
00:03:49,893 --> 00:03:50,847
‫So we placed our playSound function here

66
00:03:54,120 --> 00:03:57,030
‫in the dependency array in order not to lie

67
00:03:57,030 --> 00:04:00,000
‫to React about the dependencies.

68
00:04:00,000 --> 00:04:03,840
‫But watch the problem that this actually creates.

69
00:04:03,840 --> 00:04:07,020
‫So as I try to update the state here now

70
00:04:07,020 --> 00:04:09,870
‫as I click here nothing really happens.

71
00:04:09,870 --> 00:04:13,350
‫I mean, we hear the sound like playing twice

72
00:04:13,350 --> 00:04:17,766
‫and very shortly it goes up and then goes down again.

73
00:04:17,766 --> 00:04:20,220
‫So you see this flicker here.

74
00:04:20,220 --> 00:04:23,100
‫And so that is a big problem.

75
00:04:23,100 --> 00:04:25,735
‫The same thing probably appears here.

76
00:04:25,735 --> 00:04:27,870
‫Now here it actually works fine

77
00:04:27,870 --> 00:04:31,470
‫but not when we click on these buttons.

78
00:04:31,470 --> 00:04:34,957
‫So let's find out what the problem here is.

79
00:04:34,957 --> 00:04:39,030
‫So each time that we click here on this button,

80
00:04:39,030 --> 00:04:43,190
‫it will set the duration and it will play the sound.

81
00:04:43,190 --> 00:04:46,290
‫Now updating the state will

82
00:04:46,290 --> 00:04:49,140
‫of course re-render the component,

83
00:04:49,140 --> 00:04:52,410
‫which will recreate this function here.

84
00:04:52,410 --> 00:04:55,560
‫So React will see a brand new function.

85
00:04:55,560 --> 00:04:59,310
‫And since this function is part of the dependency array

86
00:04:59,310 --> 00:05:03,390
‫of this effect, it will then run this effect as well.

87
00:05:03,390 --> 00:05:05,670
‫And so that's where the duration is

88
00:05:05,670 --> 00:05:09,060
‫then set again but using the current values,

89
00:05:09,060 --> 00:05:11,160
‫which actually haven't changed.

90
00:05:11,160 --> 00:05:14,760
‫So when we click here, none of these four values changes.

91
00:05:14,760 --> 00:05:17,310
‫And so when the duration is then set here

92
00:05:17,310 --> 00:05:21,270
‫for the second time, it will use these values again,

93
00:05:21,270 --> 00:05:23,610
‫which will make it so that the duration

94
00:05:23,610 --> 00:05:25,500
‫immediately goes back.

95
00:05:25,500 --> 00:05:27,960
‫And so that's why we see that flashing.

96
00:05:27,960 --> 00:05:32,190
‫So for a fraction of a second it'll go to 53,

97
00:05:32,190 --> 00:05:34,323
‫but then immediately it'll go back.

98
00:05:35,160 --> 00:05:37,140
‫So saw that here.

99
00:05:37,140 --> 00:05:39,840
‫So that is the reason why this is happening

100
00:05:39,840 --> 00:05:43,710
‫and also why we kind of hear the sound twice.

101
00:05:43,710 --> 00:05:45,314
‫So we hear it here

102
00:05:45,314 --> 00:05:50,032
‫and we then hear it again from this effect.

103
00:05:50,032 --> 00:05:52,950
‫So what can we do?

104
00:05:52,950 --> 00:05:56,663
‫Well, as we learned in that lecture about the strategies

105
00:05:56,663 --> 00:06:01,663
‫on how to deal with helper functions, which this clearly is,

106
00:06:01,980 --> 00:06:04,479
‫there is a few things that we can do.

107
00:06:04,479 --> 00:06:07,860
‫So the best strategy is always to move

108
00:06:07,860 --> 00:06:11,580
‫a function like this out of the component.

109
00:06:11,580 --> 00:06:15,000
‫However, that doesn't work because this function is

110
00:06:15,000 --> 00:06:18,747
‫of course a reactive value that depends on this prop

111
00:06:18,747 --> 00:06:22,170
‫and so we cannot move it outside.

112
00:06:22,170 --> 00:06:24,690
‫Then the other strategy would be to take

113
00:06:24,690 --> 00:06:28,337
‫the function and move it into the useEffect.

114
00:06:28,337 --> 00:06:31,260
‫So right into here.

115
00:06:31,260 --> 00:06:33,720
‫But then the problem with that would be

116
00:06:33,720 --> 00:06:36,750
‫that we could no longer use it out here.

117
00:06:36,750 --> 00:06:38,970
‫And so this is the situation where we need

118
00:06:38,970 --> 00:06:41,430
‫that function in multiple places.

119
00:06:41,430 --> 00:06:46,020
‫And so then what we have to do is to memorize the function.

120
00:06:46,020 --> 00:06:48,720
‫And so then the function will not be recreated

121
00:06:48,720 --> 00:06:50,699
‫between these renders.

122
00:06:50,699 --> 00:06:54,127
‫So let's do that, useCallback.

123
00:06:59,280 --> 00:07:04,280
‫And then here in the dependency array

124
00:07:04,470 --> 00:07:07,113
‫what do you think we will need to place there?

125
00:07:08,040 --> 00:07:12,570
‫Well, we will need for sure this allowSound variable

126
00:07:12,570 --> 00:07:15,300
‫because this is a reactive value.

127
00:07:15,300 --> 00:07:18,210
‫So a value that can change over time.

128
00:07:18,210 --> 00:07:20,610
‫But what about this click sound?

129
00:07:20,610 --> 00:07:22,740
‫Well, this one, not really.

130
00:07:22,740 --> 00:07:26,370
‫So this is never gonna change and React knows that.

131
00:07:26,370 --> 00:07:30,690
‫And therefore if we now save this, we get no warnings.

132
00:07:30,690 --> 00:07:34,770
‫So meaning that our dependency array is complete.

133
00:07:34,770 --> 00:07:37,648
‫And so if we try this now again,

134
00:07:37,648 --> 00:07:41,220
‫then it is actually back to working.

135
00:07:41,220 --> 00:07:43,845
‫And it does work everywhere.

136
00:07:43,845 --> 00:07:48,845
‫Nice, so yet another use case of the useCallback hook.

137
00:07:49,549 --> 00:07:52,168
‫Now one very interesting consequence is

138
00:07:52,168 --> 00:07:55,680
‫that now as we click on this button

139
00:07:55,680 --> 00:07:59,433
‫so on this icon right here, it will actually play a sound.

140
00:08:01,320 --> 00:08:02,730
‫So did you hear that?

141
00:08:02,730 --> 00:08:05,430
‫Not when we turn it off.

142
00:08:05,430 --> 00:08:09,480
‫But when we turn it back on, it will play a sound.

143
00:08:09,480 --> 00:08:11,970
‫So that's a bit strange, right?

144
00:08:11,970 --> 00:08:14,160
‫So why is that happening?

145
00:08:14,160 --> 00:08:19,160
‫Well, notice how here allowSound is in the dependency array

146
00:08:19,740 --> 00:08:23,340
‫of useCallback, which means that this function here

147
00:08:23,340 --> 00:08:26,220
‫actually does get recreated each time

148
00:08:26,220 --> 00:08:28,260
‫that allowSound changes.

149
00:08:28,260 --> 00:08:31,306
‫Therefore when we toggle this icon here

150
00:08:31,306 --> 00:08:33,810
‫we get a new function,

151
00:08:33,810 --> 00:08:38,580
‫which then in turn will make this effect here run again.

152
00:08:38,580 --> 00:08:41,493
‫And so that's where then the sound is played.

153
00:08:44,147 --> 00:08:47,094
‫So this can quickly become confusing when you use

154
00:08:47,094 --> 00:08:51,690
‫all these useCallbacks and useEffects in your code.

155
00:08:51,690 --> 00:08:55,290
‫And let's see how this actually becomes even worse.

156
00:08:55,290 --> 00:08:59,370
‫Because let me now update the state here a little bit,

157
00:08:59,370 --> 00:09:02,924
‫and then watch what happens when I click here.

158
00:09:02,924 --> 00:09:07,924
‫So you saw that it basically reset our state.

159
00:09:08,380 --> 00:09:12,098
‫So very strange, very confusing probably.

160
00:09:12,098 --> 00:09:16,500
‫But again, it is actually for the exact same reason

161
00:09:16,500 --> 00:09:20,640
‫that earlier we heard the sound when we click here.

162
00:09:20,640 --> 00:09:23,910
‫So the reason for that is once again,

163
00:09:23,910 --> 00:09:27,930
‫that whenever we click on that icon

164
00:09:27,930 --> 00:09:30,360
‫the allowSound state changes

165
00:09:30,360 --> 00:09:33,120
‫and so then the function is recreated.

166
00:09:33,120 --> 00:09:37,260
‫So then on that update, React sees a new function.

167
00:09:37,260 --> 00:09:40,500
‫And since that function is here in the dependency array,

168
00:09:40,500 --> 00:09:43,320
‫it will run this effect again.

169
00:09:43,320 --> 00:09:47,550
‫And so this effect will run with the current values

170
00:09:47,550 --> 00:09:49,710
‫of these four pieces of state.

171
00:09:49,710 --> 00:09:53,700
‫And so it will recalculate the duration based on that.

172
00:09:53,700 --> 00:09:57,510
‫Basically ignoring that earlier we had manually changed

173
00:09:57,510 --> 00:09:59,373
‫the duration with these buttons.

174
00:10:00,475 --> 00:10:03,935
‫So of course, I did all this on purpose.

175
00:10:03,935 --> 00:10:07,860
‫So I created this kind of sophisticated example

176
00:10:07,860 --> 00:10:10,320
‫to show you all these consequences

177
00:10:10,320 --> 00:10:12,750
‫that these hooks can have in our code.

178
00:10:12,750 --> 00:10:14,970
‫Just so I could show you the thought process

179
00:10:14,970 --> 00:10:18,265
‫behind analyzing what happens here so that you can

180
00:10:18,265 --> 00:10:22,380
‫in the future think about this stuff on your own.

181
00:10:22,380 --> 00:10:25,688
‫So I think that this is really, really important

182
00:10:25,688 --> 00:10:30,031
‫and will make you a better React developer for sure.

183
00:10:30,031 --> 00:10:33,420
‫Now, the solution for this problem is

184
00:10:33,420 --> 00:10:35,688
‫to do something completely different.

185
00:10:35,688 --> 00:10:39,000
‫So instead of using useCallback here

186
00:10:39,000 --> 00:10:42,540
‫and instead of playing the sound here and here,

187
00:10:42,540 --> 00:10:45,270
‫we can do something entirely different.

188
00:10:45,270 --> 00:10:47,430
‫So let's think about this.

189
00:10:47,430 --> 00:10:51,030
‫When do we actually want the sound to play?

190
00:10:51,030 --> 00:10:55,055
‫We want it to play whenever the duration changes.

191
00:10:55,055 --> 00:11:00,055
‫So that's why we placed this function in these three places.

192
00:11:00,179 --> 00:11:04,860
‫However, as I just said, there is a better way of doing that

193
00:11:04,860 --> 00:11:08,910
‫and one that is way more clear and more intentional,

194
00:11:08,910 --> 00:11:12,780
‫which is to simply synchronize this side effect

195
00:11:12,780 --> 00:11:16,204
‫of playing the sound with the duration state.

196
00:11:16,204 --> 00:11:19,650
‫So instead of all this that we just did is

197
00:11:19,650 --> 00:11:22,800
‫to create a new separate effect

198
00:11:22,800 --> 00:11:27,118
‫which will be responsible for playing the sound.

199
00:11:27,118 --> 00:11:30,900
‫So basically for keeping the sound synchronized

200
00:11:30,900 --> 00:11:34,203
‫with the duration state.

201
00:11:38,221 --> 00:11:42,030
‫And now thanks to this,

202
00:11:42,030 --> 00:11:46,560
‫so now that we no longer need this function right here

203
00:11:46,560 --> 00:11:48,900
‫we can take the function,

204
00:11:48,900 --> 00:11:53,490
‫but let me comment it out and leave it here for you.

205
00:11:53,490 --> 00:11:55,960
‫But we can now take this function

206
00:11:57,592 --> 00:12:02,592
‫and un-comment it and remove the useCallback

207
00:12:03,360 --> 00:12:06,943
‫of course and what's this?

208
00:12:09,594 --> 00:12:12,677
‫(stutters pensively)

209
00:12:15,240 --> 00:12:20,240
‫Ah, it's function not whatever I had there earlier.

210
00:12:21,546 --> 00:12:26,546
‫So anyway now we can remove play sound from all of here,

211
00:12:27,210 --> 00:12:30,300
‫remove this of course from the dependency array,

212
00:12:30,300 --> 00:12:33,150
‫which is what we wanted all along.

213
00:12:33,150 --> 00:12:35,163
‫And then remove it from here as well.

214
00:12:36,990 --> 00:12:38,913
‫So take all of that away.

215
00:12:41,010 --> 00:12:46,010
‫And so now here is where we want to call that function.

216
00:12:46,020 --> 00:12:49,560
‫And so again, this time we were able

217
00:12:49,560 --> 00:12:53,610
‫to finally move the helper function into the effect.

218
00:12:53,610 --> 00:12:56,250
‫And so this is also great demonstration

219
00:12:56,250 --> 00:12:59,220
‫that we should in fact have one effect

220
00:12:59,220 --> 00:13:02,910
‫for each side effect that we want to have.

221
00:13:02,910 --> 00:13:06,180
‫Or in other words, this effect here should

222
00:13:06,180 --> 00:13:09,540
‫only be responsible for setting the duration,

223
00:13:09,540 --> 00:13:13,500
‫not for setting the duration and playing a sound.

224
00:13:13,500 --> 00:13:16,500
‫So instead we just create one effect

225
00:13:16,500 --> 00:13:19,620
‫that is responsible for playing the sound.

226
00:13:19,620 --> 00:13:22,733
‫And we do that whenever the duration changes.

227
00:13:22,733 --> 00:13:27,002
‫So here we actually like voluntarily declared

228
00:13:27,002 --> 00:13:30,540
‫this duration variable in the dependency array,

229
00:13:30,540 --> 00:13:33,169
‫even though we are not using it anywhere here.

230
00:13:33,169 --> 00:13:36,960
‫So this is simply to tell the effect that we wanted

231
00:13:36,960 --> 00:13:40,050
‫to run whenever the duration changes.

232
00:13:40,050 --> 00:13:44,403
‫And now here we are then missing this reactive value again.

233
00:13:45,574 --> 00:13:48,090
‫So let's place that here.

234
00:13:48,090 --> 00:13:51,448
‫And with this, everything should be well.

235
00:13:51,448 --> 00:13:56,448
‫So let's just reload this and now it works here,

236
00:13:56,460 --> 00:13:57,810
‫it works here.

237
00:13:57,810 --> 00:14:00,660
‫So both the sound and the functionality.

238
00:14:00,660 --> 00:14:04,860
‫And when I click here, it will not reset anything.

239
00:14:04,860 --> 00:14:07,680
‫So it's gonna work just as expected.

240
00:14:07,680 --> 00:14:09,653
‫And also just like before

241
00:14:09,653 --> 00:14:13,110
‫when I now click here, the sound will play.

242
00:14:13,110 --> 00:14:16,380
‫And so the reason for that is this allowSound variable

243
00:14:16,380 --> 00:14:19,020
‫right here in the dependency array.

244
00:14:19,020 --> 00:14:22,440
‫So causing this play sound function to play,

245
00:14:22,440 --> 00:14:25,440
‫which even makes sense in this situation.

246
00:14:25,440 --> 00:14:28,740
‫So when we turn it off, we hear no sound.

247
00:14:28,740 --> 00:14:31,339
‫And then just as an indication that it worked,

248
00:14:31,339 --> 00:14:35,137
‫we immediately get that sound feedback.

249
00:14:35,137 --> 00:14:39,690
‫Nice, so this was quite a journey where we explored

250
00:14:39,690 --> 00:14:43,410
‫a little bit deeper how these dependency array works.

251
00:14:43,410 --> 00:14:47,250
‫And how these different hooks interact with one another.

252
00:14:47,250 --> 00:14:49,770
‫So that thought process that I showed you

253
00:14:49,770 --> 00:14:51,510
‫I think is pretty important.

254
00:14:51,510 --> 00:14:54,076
‫And so I hope that you liked this lecture.

255
00:14:54,076 --> 00:14:57,180
‫So this deep dive into useEffect

256
00:14:57,180 --> 00:14:59,100
‫and into all the techniques

257
00:14:59,100 --> 00:15:00,993
‫that we can use together with it.

