1
00:00:02,000 --> 00:00:05,000
So how can we work around that problem?

2
00:00:05,000 --> 00:00:09,000
This is such a common problem and such a common scenario

3
00:00:09,000 --> 00:00:12,000
that React has a solution for it.

4
00:00:12,000 --> 00:00:15,000
There is another hook which you can import from React

5
00:00:15,000 --> 00:00:17,000
and that's the useEffect hook.

6
00:00:18,000 --> 00:00:23,000
UseEffect is a hook that allows you to run some code

7
00:00:23,000 --> 00:00:25,000
under certain conditions.

8
00:00:25,000 --> 00:00:28,000
At the moment this code for sending the request

9
00:00:28,000 --> 00:00:32,000
runs always when the component function runs.

10
00:00:32,000 --> 00:00:36,000
With useEffect we'll be able to restrict this

11
00:00:36,000 --> 00:00:40,000
and define conditions when this code should run.

12
00:00:40,000 --> 00:00:44,000
So that it does not always run.

13
00:00:44,000 --> 00:00:46,000
For this we call useEffect

14
00:00:46,000 --> 00:00:48,000
we execute this useEffect function

15
00:00:48,000 --> 00:00:52,000
directly in our component function

16
00:00:52,000 --> 00:00:56,000
and then useEffect once two arguments.

17
00:00:56,000 --> 00:00:59,000
The first argument is a function.

18
00:00:59,000 --> 00:01:03,000
And here I will pass in an anonymous arrow function.

19
00:01:03,000 --> 00:01:06,000
The second argument is an array

20
00:01:06,000 --> 00:01:09,000
and array of dependencies.

21
00:01:09,000 --> 00:01:11,000
And I'll come back to this array in a second.

22
00:01:12,000 --> 00:01:16,000
Now, inside of this first argument inside of this function

23
00:01:16,000 --> 00:01:19,000
we can execute our batch code here.

24
00:01:19,000 --> 00:01:24,000
So cut this and add this into this effect function.

25
00:01:25,000 --> 00:01:28,000
Now this effect function is first argument here

26
00:01:28,000 --> 00:01:30,000
which we passed to useEffect

27
00:01:30,000 --> 00:01:34,000
will be executed by React on our behalf.

28
00:01:34,000 --> 00:01:37,000
But only under certain circumstances

29
00:01:37,000 --> 00:01:40,000
not always when this component re-runs.

30
00:01:40,000 --> 00:01:44,000
I'll come back to those circumstances in a second.

31
00:01:44,000 --> 00:01:47,000
Now with that, we make sure that our fetch request here

32
00:01:47,000 --> 00:01:50,000
our fetch function is only executed

33
00:01:50,000 --> 00:01:54,000
when React executes this function.

34
00:01:54,000 --> 00:01:58,000
Now when does React execute this function though?

35
00:01:58,000 --> 00:02:02,000
If we would not specify this second argument this array.

36
00:02:02,000 --> 00:02:04,000
If we would omit this

37
00:02:04,000 --> 00:02:07,000
then this effect function would execute

38
00:02:07,000 --> 00:02:10,000
whenever this component function executes.

39
00:02:10,000 --> 00:02:13,000
So then we don't gain anything.

40
00:02:13,000 --> 00:02:16,000
That's why you need this second argument.

41
00:02:16,000 --> 00:02:18,000
You technically don't need it.

42
00:02:18,000 --> 00:02:20,000
It's not required, but if you omit it

43
00:02:20,000 --> 00:02:24,000
there is no difference compared to just running the code

44
00:02:24,000 --> 00:02:25,000
in the component function.

45
00:02:26,000 --> 00:02:29,000
With this second argument added though

46
00:02:29,000 --> 00:02:30,000
React will check

47
00:02:30,000 --> 00:02:32,000
the values

48
00:02:32,000 --> 00:02:34,000
you add, to this array

49
00:02:34,000 --> 00:02:38,000
and compare them to their equivalents

50
00:02:38,000 --> 00:02:42,000
when this effect function was executed the last time.

51
00:02:42,000 --> 00:02:46,000
Now, if that's an empty array, there are no dependencies.

52
00:02:46,000 --> 00:02:50,000
And then React will only execute this function

53
00:02:50,000 --> 00:02:53,000
when this component function rendered and executed

54
00:02:53,000 --> 00:02:55,000
for the first time.

55
00:02:55,000 --> 00:02:59,000
And for subsequent executions of this component function

56
00:02:59,000 --> 00:03:02,000
this effect function will not run

57
00:03:02,000 --> 00:03:04,000
because we have no dependencies

58
00:03:04,000 --> 00:03:08,000
so the values of the dependencies are always the same

59
00:03:08,000 --> 00:03:11,000
because there are no values.

60
00:03:12,000 --> 00:03:16,000
Now, if you would add a dependency here, like let's say

61
00:03:16,000 --> 00:03:19,000
the Isloading state snapshot

62
00:03:19,000 --> 00:03:21,000
which you should not.

63
00:03:21,000 --> 00:03:24,000
But if we would have this as a dependency here

64
00:03:24,000 --> 00:03:28,000
then this function would execute whenever the value of

65
00:03:28,000 --> 00:03:30,000
Isloading changed.

66
00:03:30,000 --> 00:03:32,000
So if that value does not change

67
00:03:32,000 --> 00:03:35,000
if that always stays the same

68
00:03:35,000 --> 00:03:37,000
then this would also not execute again.

69
00:03:37,000 --> 00:03:40,000
But if Isloading was false

70
00:03:40,000 --> 00:03:44,000
and then you somewhere update it's state to true,

71
00:03:44,000 --> 00:03:47,000
then the value of Isloading would have changed

72
00:03:47,000 --> 00:03:51,000
and then this effect function would execute again.

73
00:03:52,000 --> 00:03:54,000
Now, in reality, you don't need to think

74
00:03:54,000 --> 00:03:58,000
which values should trigger your effect function

75
00:03:58,000 --> 00:04:00,000
instead there is a simple rule.

76
00:04:00,000 --> 00:04:02,000
In your dependencies array

77
00:04:02,000 --> 00:04:06,000
you should add all external values

78
00:04:06,000 --> 00:04:09,000
your effect function relies on.

79
00:04:09,000 --> 00:04:13,000
So in this case, there are no external values.

80
00:04:13,000 --> 00:04:16,000
The fetch function is a built in browser function

81
00:04:16,000 --> 00:04:19,000
it's not one of our component props or state.

82
00:04:19,000 --> 00:04:24,000
And other than that we don't use any state or prop values

83
00:04:24,000 --> 00:04:28,000
in this effect function that would belong to our component.

84
00:04:28,000 --> 00:04:31,000
If we would extract some data from props here though

85
00:04:31,000 --> 00:04:34,000
if we would, for example, get the URL

86
00:04:34,000 --> 00:04:37,000
from props.url let's say

87
00:04:37,000 --> 00:04:39,000
then props would be a dependency

88
00:04:39,000 --> 00:04:42,000
and we should add props here.

89
00:04:42,000 --> 00:04:43,000
But that's not the case here

90
00:04:43,000 --> 00:04:46,000
but that is how it would (indistinct) then.

91
00:04:46,000 --> 00:04:48,000
Set Isoading and set loaded meetups

92
00:04:48,000 --> 00:04:52,000
actually technically would be external dependencies

93
00:04:52,000 --> 00:04:55,000
because these are constants defined outside

94
00:04:55,000 --> 00:04:57,000
of this effect function.

95
00:04:57,000 --> 00:05:01,000
But these state updating functions are an exception.

96
00:05:01,000 --> 00:05:05,000
You can add them here and that would not be incorrect

97
00:05:05,000 --> 00:05:09,000
that these functions are external dependencies.

98
00:05:09,000 --> 00:05:11,000
And whenever these functions change

99
00:05:11,000 --> 00:05:13,000
this effect should run again

100
00:05:13,000 --> 00:05:16,000
because then these functions might do different things

101
00:05:16,000 --> 00:05:19,000
than they did the last time they were executed

102
00:05:19,000 --> 00:05:22,000
but React actually guarantees that these

103
00:05:22,000 --> 00:05:26,000
state updating functions will never change.

104
00:05:26,000 --> 00:05:29,000
They will always do exactly the same thing.

105
00:05:29,000 --> 00:05:34,000
And therefore it's allowed to omit these functions here.

106
00:05:34,000 --> 00:05:38,000
And hence in our scenario here, we use useEffect like this.

107
00:05:38,000 --> 00:05:40,000
With an empty dependencies array

108
00:05:40,000 --> 00:05:44,000
since we have no external dependencies here

109
00:05:44,000 --> 00:05:47,000
and therefore this code will only run once

110
00:05:47,000 --> 00:05:51,000
when this component is rendered for the first time.

111
00:05:52,000 --> 00:05:57,000
Now I dive way deeper into useEffect with more examples

112
00:05:57,000 --> 00:06:02,000
and also more features of this hook in my course.

113
00:06:02,000 --> 00:06:06,000
But what you learn here, is the core foundation of useEffect

114
00:06:06,000 --> 00:06:08,000
which you have to understand

115
00:06:08,000 --> 00:06:12,000
that you can use it for running such side effects

116
00:06:12,000 --> 00:06:13,000
as they are called.

117
00:06:13,000 --> 00:06:16,000
Code which does not directly influence

118
00:06:16,000 --> 00:06:18,000
what's showing up on the screen.

119
00:06:18,000 --> 00:06:20,000
And that for such side effects

120
00:06:20,000 --> 00:06:22,000
useEffect is the proper solution

121
00:06:22,000 --> 00:06:26,000
for controlling when this code should run.

122
00:06:27,000 --> 00:06:30,000
Now with that, we actually should also set

123
00:06:30,000 --> 00:06:32,000
Isloading to true here

124
00:06:32,000 --> 00:06:35,000
at the beginning of this effect function

125
00:06:35,000 --> 00:06:38,000
so that whenever this affect would run again

126
00:06:38,000 --> 00:06:40,000
we set this to true again.

127
00:06:40,000 --> 00:06:43,000
It does run again here, but still that is cleaner.

128
00:06:43,000 --> 00:06:44,000
I would argue.

129
00:06:44,000 --> 00:06:47,000
And then we sent this request and ultimately

130
00:06:47,000 --> 00:06:49,000
we update our loading state again

131
00:06:49,000 --> 00:06:54,000
and we set our loaded meetups to the data we fetched here.

132
00:06:54,000 --> 00:06:57,000
And now with that, its still won't work

133
00:06:57,000 --> 00:07:00,000
because setting the data like this is incorrect

134
00:07:00,000 --> 00:07:01,000
as it turns out

135
00:07:01,000 --> 00:07:04,000
but we don't have an infinite loop.

136
00:07:04,000 --> 00:07:08,000
And I hope I could make it clear why that's the case.

137
00:07:08,000 --> 00:07:11,000
If we now save everything, our app crashes

138
00:07:11,000 --> 00:07:14,000
because as I said, we're setting the wrong data

139
00:07:14,000 --> 00:07:16,000
but we don't have an infinite loop.

140
00:07:16,000 --> 00:07:19,000
So now what's wrong with that data though.

141
00:07:19,000 --> 00:07:21,000
The problem with our data is that

142
00:07:21,000 --> 00:07:24,000
when we fetch meetups from Firebase,

143
00:07:24,000 --> 00:07:27,000
we actually don't get an array.

144
00:07:27,000 --> 00:07:30,000
Instead, we get an object where these

145
00:07:30,000 --> 00:07:34,000
cryptic auto-generated IDs

146
00:07:34,000 --> 00:07:36,000
act as properties.

147
00:07:36,000 --> 00:07:40,000
So when we send the get request to our Firebase API

148
00:07:40,000 --> 00:07:44,000
we get back an object with two properties in this case

149
00:07:44,000 --> 00:07:46,000
and these here are our property names.

150
00:07:46,000 --> 00:07:50,000
And then nest it inside of these properties

151
00:07:50,000 --> 00:07:54,000
we got nested objects with the actual meetup data.

152
00:07:55,000 --> 00:07:57,000
Now here in our component though

153
00:07:57,000 --> 00:07:59,000
we expect an array.

154
00:07:59,000 --> 00:08:04,000
Because in meetup list we map on our data

155
00:08:04,000 --> 00:08:08,000
and that only exists on an array, not on our object.

156
00:08:08,000 --> 00:08:12,000
Hence we need to transform the data here in all meetups

157
00:08:12,000 --> 00:08:15,000
before we set our state.

158
00:08:15,000 --> 00:08:16,000
Once we fetched the data

159
00:08:16,000 --> 00:08:19,000
so in this second, then block here

160
00:08:19,000 --> 00:08:21,000
we wanna transform the data.

161
00:08:21,000 --> 00:08:25,000
And we can do this for creating a helper array here

162
00:08:25,000 --> 00:08:26,000
meetups like this.

163
00:08:26,000 --> 00:08:30,000
And then a four in loop where we go through

164
00:08:30,000 --> 00:08:32,000
all our keys in data.

165
00:08:32,000 --> 00:08:35,000
So all the keys in this data object

166
00:08:35,000 --> 00:08:37,000
we fetch from Firebase.

167
00:08:37,000 --> 00:08:40,000
And these keys will be this

168
00:08:40,000 --> 00:08:42,000
random IDs here.

169
00:08:42,000 --> 00:08:45,000
These unique IDs that will be our keys.

170
00:08:45,000 --> 00:08:48,000
And then we create a new meetup here

171
00:08:49,000 --> 00:08:52,000
for every key through which we loop.

172
00:08:52,000 --> 00:08:55,000
So for every meetup that's stored on Firebase

173
00:08:55,000 --> 00:08:58,000
and we can set the ID equal to key

174
00:08:58,000 --> 00:09:02,000
since that is that auto-generated ID.

175
00:09:02,000 --> 00:09:07,000
And then just distribute data key into this object.

176
00:09:07,000 --> 00:09:10,000
So we access the nested object for the given key.

177
00:09:10,000 --> 00:09:13,000
So we access the nested object here.

178
00:09:13,000 --> 00:09:15,000
And then we just use the spread operator

179
00:09:15,000 --> 00:09:18,000
which is a default JavaScript operator

180
00:09:18,000 --> 00:09:22,000
to copy all the key value pairs of this nested object

181
00:09:22,000 --> 00:09:23,000
into this object.

182
00:09:24,000 --> 00:09:28,000
And that constructs meetup object as we needed.

183
00:09:28,000 --> 00:09:31,000
And then we just need to push that onto

184
00:09:31,000 --> 00:09:33,000
our helper array here.

185
00:09:33,000 --> 00:09:35,000
And then it's this helper meetups array

186
00:09:35,000 --> 00:09:40,000
which we wanna set as our loaded meetups data.

187
00:09:41,000 --> 00:09:45,000
And now if we do that, if we transform the data like this

188
00:09:45,000 --> 00:09:50,000
if we save this and reload, we see loading briefly

189
00:09:50,000 --> 00:09:53,000
but then we see all our meetups.

190
00:09:53,000 --> 00:09:57,000
And that's how we can fetch data in this case from Firebase

191
00:09:57,000 --> 00:10:00,000
but in general with useEffect

192
00:10:00,000 --> 00:10:03,000
fetching data with a loading and a data state

193
00:10:03,000 --> 00:10:05,000
without causing an infinite loop.

