1
00:00:02,000 --> 00:00:05,000
Now that we can add data to Firebase,

2
00:00:05,000 --> 00:00:07,000
so that we can store data on a server

3
00:00:07,000 --> 00:00:11,000
and that we can fetch data whenever we visit all meetups,

4
00:00:11,000 --> 00:00:14,000
now with that we got the core functionality built in.

5
00:00:14,000 --> 00:00:17,000
The last feature, which I wanna add here

6
00:00:17,000 --> 00:00:19,000
is this favorites feature.

7
00:00:19,000 --> 00:00:21,000
This button here should be clickable

8
00:00:21,000 --> 00:00:24,000
and when we click it, this meetup should

9
00:00:24,000 --> 00:00:27,000
be added to our favorites.

10
00:00:27,000 --> 00:00:29,000
Then on the my favorites page

11
00:00:29,000 --> 00:00:31,000
I wanna see a list of all my favorites

12
00:00:31,000 --> 00:00:34,000
and of course, as soon as item is a favorite

13
00:00:34,000 --> 00:00:37,000
I want to be able to unfavorite it.

14
00:00:37,000 --> 00:00:41,000
And then I also want to show a little badge here

15
00:00:41,000 --> 00:00:44,000
in the navigation next to my favorites

16
00:00:44,000 --> 00:00:48,000
where we see the current count of favorites.

17
00:00:48,000 --> 00:00:50,000
That's the last feature I wanna add.

18
00:00:50,000 --> 00:00:54,000
And for this we'll need to manage some state

19
00:00:54,000 --> 00:00:57,000
which affects more than one component.

20
00:00:57,000 --> 00:01:01,000
Because our list of favorites is some state

21
00:01:01,000 --> 00:01:04,000
that should cause the UI to update

22
00:01:04,000 --> 00:01:07,000
because we, for example, will have that badge here,

23
00:01:07,000 --> 00:01:10,000
which shows the current number of favorites.

24
00:01:10,000 --> 00:01:12,000
And of course this button should change once

25
00:01:12,000 --> 00:01:14,000
our item is a favorite.

26
00:01:14,000 --> 00:01:16,000
So we'll have different parts

27
00:01:16,000 --> 00:01:20,000
of this application that will be affected by our state.

28
00:01:20,000 --> 00:01:23,000
And because that's the case, because we'll have

29
00:01:23,000 --> 00:01:26,000
a state that affects more than one component

30
00:01:26,000 --> 00:01:31,000
we will need a mechanism of managing that state globally

31
00:01:31,000 --> 00:01:36,000
and distributing that state to different components.

32
00:01:36,000 --> 00:01:40,000
Because just using use state inside of a single component

33
00:01:40,000 --> 00:01:44,000
doesn't necessarily do the trick anymore,

34
00:01:44,000 --> 00:01:46,000
because that only affects one component.

35
00:01:47,000 --> 00:01:52,000
Now, one thing we could do is we could lift the state up.

36
00:01:53,000 --> 00:01:55,000
That means that we could, for example

37
00:01:55,000 --> 00:01:58,000
manage our favorites state in app JS,

38
00:01:58,000 --> 00:02:01,000
and then we pass it into all the components

39
00:02:01,000 --> 00:02:04,000
that are interested as props.

40
00:02:04,000 --> 00:02:06,000
So to the layout component which

41
00:02:06,000 --> 00:02:08,000
has access to the main navigation component,

42
00:02:08,000 --> 00:02:11,000
which is where I wanna show this badge in the end,

43
00:02:11,000 --> 00:02:14,000
to that component we could pass the number

44
00:02:14,000 --> 00:02:17,000
of favorites if we manage the favorites state

45
00:02:17,000 --> 00:02:20,000
in the app component, and then to

46
00:02:20,000 --> 00:02:22,000
the favorites page component we could

47
00:02:22,000 --> 00:02:25,000
pass the array of favorite meetups.

48
00:02:25,000 --> 00:02:28,000
So we could manage the state here in the app component

49
00:02:28,000 --> 00:02:31,000
and then just distribute it through props.

50
00:02:32,000 --> 00:02:37,000
That would work, but it has a couple of downsides.

51
00:02:37,000 --> 00:02:40,000
One problem would be that if we have a bigger application

52
00:02:40,000 --> 00:02:44,000
with different States that affect different components

53
00:02:44,000 --> 00:02:47,000
we have to manage more and more state in

54
00:02:47,000 --> 00:02:50,000
this app component, and hence this app component

55
00:02:50,000 --> 00:02:54,000
becomes bigger and bigger and that's maybe not ideal.

56
00:02:54,000 --> 00:02:59,000
Another problem is that if we pass states down through props

57
00:02:59,000 --> 00:03:03,000
that we can end up with very long prop chains.

58
00:03:03,000 --> 00:03:07,000
We pass the number of favorites to the layout component

59
00:03:07,000 --> 00:03:10,000
and from there we pass it into main navigation.

60
00:03:10,000 --> 00:03:13,000
So we already passed props to layout

61
00:03:13,000 --> 00:03:16,000
just so that this component can then

62
00:03:16,000 --> 00:03:20,000
pass that data on to another component.

63
00:03:20,000 --> 00:03:22,000
Whilst that is not horrible

64
00:03:22,000 --> 00:03:25,000
it's also not necessarily great.

65
00:03:25,000 --> 00:03:30,000
And it can also make our code a bit harder to maintain.

66
00:03:30,000 --> 00:03:32,000
And because we have issues like this

67
00:03:32,000 --> 00:03:34,000
there are state management solutions

68
00:03:34,000 --> 00:03:37,000
for managing application wide state

69
00:03:37,000 --> 00:03:39,000
in a more convenient way.

70
00:03:39,000 --> 00:03:44,000
One very popular state management package is Redux.

71
00:03:44,000 --> 00:03:47,000
I cover it in my course, but for many scenarios

72
00:03:47,000 --> 00:03:51,000
we don't even need Redux, because react also has a built

73
00:03:51,000 --> 00:03:56,000
in state management solution for application wide state.

74
00:03:56,000 --> 00:03:59,000
And that's a feature called context.

75
00:03:59,000 --> 00:04:02,000
Now for this to add this context feature,

76
00:04:02,000 --> 00:04:05,000
I'll add a new folder in the source folder

77
00:04:05,000 --> 00:04:07,000
and I'll name it store.

78
00:04:07,000 --> 00:04:08,000
The folder name is up to you

79
00:04:08,000 --> 00:04:11,000
but store is a common convention

80
00:04:11,000 --> 00:04:15,000
since we will set up the state store for this application.

81
00:04:16,000 --> 00:04:21,000
Instead of store, I'll add a favorite stash context JS file

82
00:04:21,000 --> 00:04:26,000
and in this file I'll now create such a context.

83
00:04:26,000 --> 00:04:28,000
For this in this file, we first of all,

84
00:04:28,000 --> 00:04:33,000
import create context from react

85
00:04:33,000 --> 00:04:36,000
so that's a function exposed by the react library

86
00:04:37,000 --> 00:04:41,000
and we can then call create context.

87
00:04:41,000 --> 00:04:45,000
And this that's what the name implies it creates a context.

88
00:04:45,000 --> 00:04:49,000
We don't know yet what exactly such a context is,

89
00:04:49,000 --> 00:04:53,000
but hey, we are creating one at least.

90
00:04:53,000 --> 00:04:56,000
Now context in the end is a JavaScript object.

91
00:04:56,000 --> 00:04:58,000
And we can store this in a constant

92
00:04:58,000 --> 00:05:01,000
and I'll name it favorites context.

93
00:05:01,000 --> 00:05:05,000
I start with a capital F because this object

94
00:05:05,000 --> 00:05:08,000
which is created by context actually

95
00:05:08,000 --> 00:05:12,000
will contain a react component.

96
00:05:12,000 --> 00:05:15,000
And when you build your own react components

97
00:05:15,000 --> 00:05:18,000
the convention which you should follow is that you start

98
00:05:18,000 --> 00:05:23,000
with a capital character for your component names.

99
00:05:23,000 --> 00:05:24,000
So that's why I store my context

100
00:05:24,000 --> 00:05:27,000
in a favorites context constant here.

101
00:05:29,000 --> 00:05:32,000
Now create context also takes an argument

102
00:05:32,000 --> 00:05:36,000
and then the argument is the initial value for that context.

103
00:05:36,000 --> 00:05:39,000
So the initial value for this application

104
00:05:39,000 --> 00:05:42,000
or component wide state.

105
00:05:42,000 --> 00:05:45,000
And that can be any value of your choice.

106
00:05:45,000 --> 00:05:47,000
It could, for example, be an object,

107
00:05:48,000 --> 00:05:51,000
let's say an object where we have a favorites key

108
00:05:51,000 --> 00:05:53,000
which is an empty array initially

109
00:05:53,000 --> 00:05:55,000
because we have no favorites at the beginning

110
00:05:55,000 --> 00:05:58,000
and maybe a total favorites key,

111
00:05:58,000 --> 00:05:59,000
which is zero initially

112
00:05:59,000 --> 00:06:02,000
which is the total number of favorites.

113
00:06:04,000 --> 00:06:06,000
That could be our context

114
00:06:06,000 --> 00:06:08,000
but like this it's not too useful

115
00:06:08,000 --> 00:06:11,000
we also need ways of changing

116
00:06:11,000 --> 00:06:15,000
these values of adding and removing favorites.

117
00:06:15,000 --> 00:06:19,000
And that's why I will also add a component in this file.

118
00:06:19,000 --> 00:06:21,000
So a component function

119
00:06:21,000 --> 00:06:24,000
which I'll name favorites context provider.

120
00:06:26,000 --> 00:06:29,000
This component will be a regular react component

121
00:06:29,000 --> 00:06:34,000
but it will have the job of providing this context

122
00:06:34,000 --> 00:06:37,000
to all the components that are interested

123
00:06:37,000 --> 00:06:39,000
in listening to the values,

124
00:06:39,000 --> 00:06:42,000
So all the components that need values

125
00:06:42,000 --> 00:06:45,000
from the context and this component here

126
00:06:45,000 --> 00:06:48,000
the favorites context provider component

127
00:06:48,000 --> 00:06:53,000
will also be responsible for updating the context values.

128
00:06:53,000 --> 00:06:57,000
Now for this what we'll do here is we'll return

129
00:06:57,000 --> 00:07:00,000
favorites context so this constant

130
00:07:00,000 --> 00:07:04,000
which we created here dot provider,

131
00:07:04,000 --> 00:07:08,000
that's a component this context object has built in.

132
00:07:09,000 --> 00:07:12,000
And this provider component needs to be wrapped

133
00:07:12,000 --> 00:07:16,000
around all the components that are interested

134
00:07:16,000 --> 00:07:18,000
in interacting with that context.

135
00:07:19,000 --> 00:07:22,000
Now, this favorites context provider component

136
00:07:22,000 --> 00:07:26,000
which we are building here itself should be wrapped

137
00:07:26,000 --> 00:07:27,000
around other components later.

138
00:07:27,000 --> 00:07:31,000
I plan on using it in index JS to wrap it

139
00:07:31,000 --> 00:07:34,000
around my entire app so that all the components

140
00:07:34,000 --> 00:07:38,000
in the app have access to the context.

141
00:07:38,000 --> 00:07:40,000
And therefore, what we can do here

142
00:07:40,000 --> 00:07:43,000
is we can accept props and simply wrap

143
00:07:43,000 --> 00:07:46,000
this provider component, which we get

144
00:07:46,000 --> 00:07:50,000
from this context object around props children.

145
00:07:50,000 --> 00:07:54,000
That means that we can now wrap our component here

146
00:07:54,000 --> 00:07:56,000
around any other components.

147
00:07:56,000 --> 00:07:58,000
And those components will be wrapped

148
00:07:58,000 --> 00:08:00,000
by context automatically.

149
00:08:00,000 --> 00:08:02,000
I hope this makes sense.

150
00:08:02,000 --> 00:08:04,000
Now why am I doing it like this?

151
00:08:04,000 --> 00:08:08,000
Because now in his favorites context provider component

152
00:08:08,000 --> 00:08:13,000
which we're building here, we can manage our context data.

153
00:08:13,000 --> 00:08:16,000
We can manage that with state,

154
00:08:16,000 --> 00:08:20,000
because this component which we are working on here

155
00:08:20,000 --> 00:08:23,000
is still a regular react component.

156
00:08:23,000 --> 00:08:25,000
So when we manage state in there,

157
00:08:25,000 --> 00:08:29,000
when we changed that state, that component here

158
00:08:29,000 --> 00:08:33,000
we'll still execute again and we'll be re-evaluated

159
00:08:33,000 --> 00:08:36,000
and that means that if we change our context value

160
00:08:36,000 --> 00:08:38,000
in this component, and we pass

161
00:08:38,000 --> 00:08:41,000
this context value to the provider

162
00:08:41,000 --> 00:08:44,000
all components that are listening

163
00:08:44,000 --> 00:08:48,000
to our context will be updated

164
00:08:48,000 --> 00:08:51,000
and will get that latest updated data.

165
00:08:51,000 --> 00:08:54,000
And in case it's not 100% clear yet

166
00:08:54,000 --> 00:08:56,000
we'll get there step-by-step

167
00:08:56,000 --> 00:08:58,000
because we're now going to add the logic for this.

168
00:09:00,000 --> 00:09:05,000
In favorites context provider I'll create a context object

169
00:09:06,000 --> 00:09:10,000
and I'll pass this context object as a value

170
00:09:10,000 --> 00:09:15,000
to favorites context dot provider, this component

171
00:09:15,000 --> 00:09:18,000
which is exposed by this favorites context object

172
00:09:18,000 --> 00:09:23,000
wants a value prop where we pass the current context value.

173
00:09:24,000 --> 00:09:29,000
We set the initial values here when we create the context

174
00:09:29,000 --> 00:09:31,000
but we can then update those values

175
00:09:31,000 --> 00:09:36,000
and pass the latest values with help of that value prop.

176
00:09:36,000 --> 00:09:38,000
And whenever that value changes

177
00:09:38,000 --> 00:09:41,000
all components that are listening

178
00:09:41,000 --> 00:09:44,000
to our context will be updated in the end.

179
00:09:44,000 --> 00:09:46,000
That's how this works.

180
00:09:46,000 --> 00:09:50,000
So now we just need to derive this context object

181
00:09:50,000 --> 00:09:52,000
and its values dynamically.

182
00:09:52,000 --> 00:09:56,000
And that's where use state comes into play now.

183
00:09:56,000 --> 00:09:58,000
We can manage some state here

184
00:09:58,000 --> 00:10:00,000
in this favorites context provider

185
00:10:00,000 --> 00:10:04,000
and we can manage an array of favorited meetups here.

186
00:10:04,000 --> 00:10:08,000
So here we have the user favorites

187
00:10:08,000 --> 00:10:11,000
let's say and a function for setting those user favorites.

188
00:10:12,000 --> 00:10:16,000
Now here this context object, which we construct

189
00:10:16,000 --> 00:10:19,000
which holds the latest values that should be exposed

190
00:10:19,000 --> 00:10:22,000
to our components, that object now

191
00:10:22,000 --> 00:10:26,000
has a favorites key because we defined

192
00:10:26,000 --> 00:10:28,000
it here in the initial context value as well.

193
00:10:28,000 --> 00:10:32,000
And we set our current user favorites array

194
00:10:32,000 --> 00:10:35,000
this state snapshot as a value.

195
00:10:35,000 --> 00:10:38,000
So when the state changes this value will change

196
00:10:38,000 --> 00:10:40,000
and will have a new context object

197
00:10:40,000 --> 00:10:44,000
and will pass this new updated context object

198
00:10:44,000 --> 00:10:47,000
to all the components that are wrapped

199
00:10:47,000 --> 00:10:48,000
by this provider in the end.

200
00:10:50,000 --> 00:10:52,000
And I'll also set total favorites here

201
00:10:52,000 --> 00:10:54,000
and that is simply user favorites dot length.

202
00:10:56,000 --> 00:10:58,000
Like this, now we just need a way

203
00:10:58,000 --> 00:11:00,000
of changing our state here.

