Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,270 --> 00:00:03,900
Now with the changes we made
2
00:00:03,900 --> 00:00:05,830
over the last lectures,
3
00:00:05,830 --> 00:00:09,350
we are able to gather our expense data,
4
00:00:09,350 --> 00:00:12,650
our user input and combine it into this object
5
00:00:12,650 --> 00:00:15,270
and clear the form thereafter.
6
00:00:15,270 --> 00:00:18,980
The only problem is that having this data is nice
7
00:00:18,980 --> 00:00:20,920
but we technically don't need it
8
00:00:20,920 --> 00:00:24,280
in the expense form component, do we?
9
00:00:24,280 --> 00:00:26,800
Instead we needed in the new expense
10
00:00:26,800 --> 00:00:30,300
or to be precise in the app JS component even
11
00:00:30,300 --> 00:00:32,910
because there we have our expenses array
12
00:00:32,910 --> 00:00:37,170
and ultimately our goal will be to add this new expense
13
00:00:37,170 --> 00:00:41,420
which the user entered to this list of existing expenses
14
00:00:41,420 --> 00:00:45,163
and we probably also wanna enrich it by adding an ID.
15
00:00:46,270 --> 00:00:49,990
So, we need to pass the data which we're collecting
16
00:00:49,990 --> 00:00:54,990
and generating in expense form to the app component.
17
00:00:55,090 --> 00:00:57,060
Now I put as point, we only learned
18
00:00:57,060 --> 00:00:59,170
how we can pass data down.
19
00:00:59,170 --> 00:01:04,170
So how we can, for example, in the expenses folder
20
00:01:04,239 --> 00:01:09,240
pass title, amount and date from the expenses component
21
00:01:10,300 --> 00:01:12,170
to the expense items component.
22
00:01:12,170 --> 00:01:15,660
So from parent to child, that's something we learned.
23
00:01:15,660 --> 00:01:17,293
We can do that with props,
24
00:01:18,190 --> 00:01:20,900
but how can we do it in the other direction
25
00:01:20,900 --> 00:01:24,130
if data is generated in the expense form
26
00:01:24,130 --> 00:01:27,463
and we then wanna pass it up to the app component?
27
00:01:28,380 --> 00:01:32,040
Well, actually we already saw how it works
28
00:01:32,040 --> 00:01:33,560
but it's easy to miss it.
29
00:01:33,560 --> 00:01:35,750
So let me show it to you again.
30
00:01:35,750 --> 00:01:39,760
In expense form, we are listening to user input
31
00:01:39,760 --> 00:01:42,370
to change this to the title input, for example
32
00:01:43,960 --> 00:01:46,520
and whenever the user types here,
33
00:01:46,520 --> 00:01:50,920
this function title change handler executes
34
00:01:50,920 --> 00:01:54,930
and there we get this default event object,
35
00:01:54,930 --> 00:01:57,620
that's something the browser gives us.
36
00:01:57,620 --> 00:02:02,470
Now, actually we can think about this input element here
37
00:02:02,470 --> 00:02:04,610
as a component as well.
38
00:02:04,610 --> 00:02:07,120
It's not one of our components
39
00:02:07,120 --> 00:02:09,789
but it is simply a pre-built component,
40
00:02:09,789 --> 00:02:13,000
we could say, provided to us by react
41
00:02:13,000 --> 00:02:16,810
and of course translate it to the input Dom element
42
00:02:16,810 --> 00:02:19,760
but it has this component character in the end
43
00:02:19,760 --> 00:02:22,710
and we do also set some props on that component
44
00:02:22,710 --> 00:02:25,743
including this special onchange prop.
45
00:02:26,590 --> 00:02:29,860
Now, actually this onchange prop isn't that special,
46
00:02:29,860 --> 00:02:32,250
it's just a prop named onchange
47
00:02:32,250 --> 00:02:36,210
which wants a function as a value
48
00:02:36,210 --> 00:02:39,240
and then internally the input element
49
00:02:39,240 --> 00:02:40,600
adds this event listener.
50
00:02:40,600 --> 00:02:43,610
So react basically sees that we set a value
51
00:02:43,610 --> 00:02:46,600
on this onchange prop and adds that listener
52
00:02:46,600 --> 00:02:48,323
on the rendered input element.
53
00:02:49,500 --> 00:02:52,380
But that is a pattern we can replicate
54
00:02:52,380 --> 00:02:54,940
for our own components as well.
55
00:02:54,940 --> 00:02:57,670
We can create our own event props,
56
00:02:57,670 --> 00:03:01,090
if we wanna call it like, and we can expect functions
57
00:03:01,090 --> 00:03:04,020
as values and that would allow us
58
00:03:04,020 --> 00:03:06,820
to pass a function from a parent component
59
00:03:06,820 --> 00:03:09,920
to a child component and then call that function
60
00:03:09,920 --> 00:03:12,170
inside of the child component.
61
00:03:12,170 --> 00:03:14,610
And when we then call a function,
62
00:03:14,610 --> 00:03:18,810
we can of course pass data to that function as a parameter
63
00:03:18,810 --> 00:03:23,083
and that's how we can communicate up from child to parent.
64
00:03:24,050 --> 00:03:25,800
Now, in case this was too quick,
65
00:03:25,800 --> 00:03:28,200
let me simply show it to you.
66
00:03:28,200 --> 00:03:31,180
Let's say we wanna pass the expense data
67
00:03:31,180 --> 00:03:33,880
which we gather in the expense form component
68
00:03:33,880 --> 00:03:37,020
to the new expense component as a first step
69
00:03:37,020 --> 00:03:40,130
because if we ultimately wanna reach the app component,
70
00:03:40,130 --> 00:03:43,370
we first of all have to reach the new expense component
71
00:03:43,370 --> 00:03:45,540
because it's the new expense component
72
00:03:45,540 --> 00:03:47,570
which uses the expense form
73
00:03:47,570 --> 00:03:50,850
and then in a second step later, it's the app component
74
00:03:50,850 --> 00:03:53,360
which use the new expense component
75
00:03:53,360 --> 00:03:56,320
but we can't skip components in between,
76
00:03:56,320 --> 00:03:57,810
that's also something you learned
77
00:03:57,810 --> 00:03:59,920
in the previous course section.
78
00:03:59,920 --> 00:04:03,290
Props can only be passed from parent to child,
79
00:04:03,290 --> 00:04:06,123
we can't skip intermediate components.
80
00:04:07,210 --> 00:04:09,680
So therefore as a first step,
81
00:04:09,680 --> 00:04:13,480
let's make sure we can pass the expense data to new expense
82
00:04:13,480 --> 00:04:17,500
and we can do it as by adding a new prop to expense form.
83
00:04:17,500 --> 00:04:20,269
It's our components, so we can name it however we want,
84
00:04:20,269 --> 00:04:25,077
but I will name it on save expense data,
85
00:04:26,530 --> 00:04:29,040
but the name is totally up to you,
86
00:04:29,040 --> 00:04:31,920
I'm just naming it on something
87
00:04:31,920 --> 00:04:33,760
because I wanna make it clear
88
00:04:33,760 --> 00:04:37,390
that the value for this prop should be a function,
89
00:04:37,390 --> 00:04:40,220
a function which will eventually be triggered
90
00:04:40,220 --> 00:04:44,140
when something happens inside of this component.
91
00:04:44,140 --> 00:04:48,380
In this case, when the user saves the entered expense data,
92
00:04:48,380 --> 00:04:50,743
so when the form is submitted in the end.
93
00:04:51,760 --> 00:04:54,120
so that's again a convention I'm following,
94
00:04:54,120 --> 00:04:55,580
you don't have to name it like this,
95
00:04:55,580 --> 00:04:57,650
you can name it however you want,
96
00:04:57,650 --> 00:04:58,840
It's totally up to you.
97
00:04:58,840 --> 00:05:01,390
It doesn't have to start with on.
98
00:05:01,390 --> 00:05:04,440
I just do start with on to follow this convention
99
00:05:04,440 --> 00:05:07,800
and to make it clear that the value for this prop
100
00:05:07,800 --> 00:05:10,730
should be a function which can then be called
101
00:05:10,730 --> 00:05:13,023
inside of the expense form component.
102
00:05:14,370 --> 00:05:18,410
Hence, it's a function we should define here in new expense
103
00:05:18,410 --> 00:05:20,860
just as we did it for the input elements
104
00:05:20,860 --> 00:05:24,010
with the functions we bound to the onchange prop,
105
00:05:24,010 --> 00:05:26,550
we define those in the expense form
106
00:05:26,550 --> 00:05:29,350
before we returned the JS Xcode as well.
107
00:05:29,350 --> 00:05:32,950
Now we're doing the same here one level above that
108
00:05:32,950 --> 00:05:34,610
in the new expense component
109
00:05:34,610 --> 00:05:37,473
for our own custom expense form component.
110
00:05:38,480 --> 00:05:43,480
So here I'll add a const save expense data handler
111
00:05:43,830 --> 00:05:47,490
and important as a parameter here,
112
00:05:47,490 --> 00:05:52,490
I will expect the entered expense data.
113
00:05:53,850 --> 00:05:57,750
The name of the parameter is up to you, it's your function
114
00:05:57,750 --> 00:06:01,350
but now I make it clear that this function expects
115
00:06:01,350 --> 00:06:03,063
to get this parameter.
116
00:06:04,760 --> 00:06:09,223
And then here we can add our expense data
117
00:06:09,223 --> 00:06:13,440
another object, copy in the entered expense data
118
00:06:13,440 --> 00:06:16,110
which I expect to be that object
119
00:06:16,110 --> 00:06:18,580
which we generate here into submit handler,
120
00:06:18,580 --> 00:06:23,580
so this object, I pull out all the key value pairs
121
00:06:23,960 --> 00:06:26,340
and add them to this new object
122
00:06:26,340 --> 00:06:30,480
and then I add in a new key, the ID key
123
00:06:30,480 --> 00:06:33,450
and simply set that to math random.
124
00:06:33,450 --> 00:06:36,900
Math random to string to convert it to a string.
125
00:06:36,900 --> 00:06:38,950
It's not a perfect unique ID,
126
00:06:38,950 --> 00:06:42,730
theoretically we could generate the same value twice
127
00:06:42,730 --> 00:06:44,573
but it's good enough for this demo.
128
00:06:45,690 --> 00:06:48,460
And then we can see what we do with that thereafter,
129
00:06:48,460 --> 00:06:52,363
for the moment I'll just log does enriched expense data.
130
00:06:53,940 --> 00:06:56,100
Now it's a pointer at this function,
131
00:06:56,100 --> 00:07:00,323
which I wanna pass as a value to all onSave expense data,
132
00:07:01,190 --> 00:07:04,090
so that this onSave expense data prop
133
00:07:04,090 --> 00:07:08,360
in my custom component receives dysfunction as a value.
134
00:07:08,360 --> 00:07:10,810
Again, I don't execute it here,
135
00:07:10,810 --> 00:07:12,490
we don't add parenthesis,
136
00:07:12,490 --> 00:07:14,550
I just point at the function,
137
00:07:14,550 --> 00:07:17,680
so that the function itself a pointer edit
138
00:07:17,680 --> 00:07:19,803
is passed to expense form.
139
00:07:21,130 --> 00:07:23,040
Now that's the first step.
140
00:07:23,040 --> 00:07:26,140
The second step now is to use this function
141
00:07:26,140 --> 00:07:28,163
inside of our accustomed component.
142
00:07:29,020 --> 00:07:31,810
That's a step we didn't have to do for the inputs
143
00:07:31,810 --> 00:07:34,920
because these are built in components basically,
144
00:07:34,920 --> 00:07:38,420
but they're also we pass a function to onchange
145
00:07:38,420 --> 00:07:41,570
and internally react and we'll add a listener
146
00:07:41,570 --> 00:07:44,190
and call this function which we pass in
147
00:07:44,190 --> 00:07:47,053
whenever that event occurs, that change event.
148
00:07:48,130 --> 00:07:50,740
Now, since we're doing this on our own custom component,
149
00:07:50,740 --> 00:07:54,090
we also have to call the past and function manually
150
00:07:54,090 --> 00:07:56,070
and that's what I'll do next.
151
00:07:56,070 --> 00:08:00,067
So inside of expense forum, we now can expect this
152
00:08:00,067 --> 00:08:03,680
onSave expense data prop because I am setting it
153
00:08:03,680 --> 00:08:06,130
when I used the expense form component,
154
00:08:06,130 --> 00:08:07,860
hence instead of expense form,
155
00:08:07,860 --> 00:08:09,730
we can extract the value past
156
00:08:09,730 --> 00:08:12,553
for this prop ie, this function.
157
00:08:13,670 --> 00:08:16,110
So, inside of expense form,
158
00:08:16,110 --> 00:08:19,460
I of course now expect to get some props
159
00:08:19,460 --> 00:08:21,890
because we're setting a prop now
160
00:08:21,890 --> 00:08:25,330
and now, inside of the submit handler,
161
00:08:25,330 --> 00:08:28,470
instead of I logging my expense data,
162
00:08:28,470 --> 00:08:33,470
I will access props onSave expense data and executed here.
163
00:08:34,570 --> 00:08:35,710
And that's not important,
164
00:08:35,710 --> 00:08:37,873
now I executed I can execute it.
165
00:08:37,873 --> 00:08:41,957
I can execute it because the value which we get on this
166
00:08:41,957 --> 00:08:45,460
onSave expense data key will be a function.
167
00:08:45,460 --> 00:08:48,293
We are passing in a function here after all.
168
00:08:49,310 --> 00:08:54,310
So it's this function defined in the new expense component
169
00:08:54,640 --> 00:08:58,290
which we will now execute in a different component,
170
00:08:58,290 --> 00:09:01,100
inside of expense them to be precise.
171
00:09:01,100 --> 00:09:03,730
And we can execute the function
172
00:09:03,730 --> 00:09:06,790
even though it's not defined inside of expense form
173
00:09:06,790 --> 00:09:09,590
because we are passing a pointer edit
174
00:09:09,590 --> 00:09:13,350
through the onSave expense data prop.
175
00:09:13,350 --> 00:09:16,330
And this is a super important pattern
176
00:09:16,330 --> 00:09:19,340
which you will use a lot in react.
177
00:09:19,340 --> 00:09:22,150
This is how you can communicate between components
178
00:09:22,150 --> 00:09:24,890
and how you can communicate up,
179
00:09:24,890 --> 00:09:28,250
how you can make sure that a child component,
180
00:09:28,250 --> 00:09:30,890
the expense form component here for example,
181
00:09:30,890 --> 00:09:33,830
can communicate up to the parent component,
182
00:09:33,830 --> 00:09:36,660
the new expense component in this case.
183
00:09:36,660 --> 00:09:39,617
We can call a function in the new expense component
184
00:09:39,617 --> 00:09:43,090
and we can pass data as a parameter.
185
00:09:43,090 --> 00:09:46,330
So here, when we call onSave expense data
186
00:09:46,330 --> 00:09:49,380
in the expense form, I can pass the expense data
187
00:09:49,380 --> 00:09:51,850
which are generated here as our argument
188
00:09:53,220 --> 00:09:55,190
and that's the value which we'll receive
189
00:09:55,190 --> 00:09:58,133
as a parameter here in new expense.
190
00:09:59,280 --> 00:10:01,600
I hope this flow is clear.
191
00:10:01,600 --> 00:10:04,120
The trick really is that we pass around
192
00:10:04,120 --> 00:10:05,743
a pointer at a function.
193
00:10:06,980 --> 00:10:09,790
Now, if we go back and I reload,
194
00:10:09,790 --> 00:10:13,640
if I again, enter something here
195
00:10:13,640 --> 00:10:16,440
and pick a date if I click add expense,
196
00:10:16,440 --> 00:10:18,920
you see this is being locked to the console
197
00:10:18,920 --> 00:10:22,900
and it's being locked from the new expense file line 12,
198
00:10:22,900 --> 00:10:24,453
so it's does log here.
199
00:10:25,550 --> 00:10:27,010
And we can tell that it's from there
200
00:10:27,010 --> 00:10:29,430
because we also have an ID field there
201
00:10:29,430 --> 00:10:31,270
which has this random number
202
00:10:31,270 --> 00:10:33,893
which has generated and converted to a string.
203
00:10:34,760 --> 00:10:37,070
And that's how we can communicate up
204
00:10:37,070 --> 00:10:39,293
and this is a super important pattern.
205
00:10:40,640 --> 00:10:44,000
Now, of course, we can continue in this chain now
206
00:10:44,000 --> 00:10:48,710
and we can communicate up from inside new expense to app
207
00:10:48,710 --> 00:10:50,820
because it's this app component which needs
208
00:10:50,820 --> 00:10:54,253
the new expense in the end to add it to this expenses array.
209
00:10:55,290 --> 00:10:59,340
So therefore again, in app JS,
210
00:10:59,340 --> 00:11:01,790
we can add a function which we defined
211
00:11:01,790 --> 00:11:04,340
before we return JS Xcode
212
00:11:04,340 --> 00:11:08,780
and we can simply name this at expense handler
213
00:11:09,680 --> 00:11:14,050
and be expect to get our expense here as a parameter
214
00:11:14,050 --> 00:11:15,580
and then we do something with it.
215
00:11:15,580 --> 00:11:20,040
And for the moment I'll just console log in app JS
216
00:11:20,040 --> 00:11:22,170
and console log the expense
217
00:11:22,170 --> 00:11:24,430
because we haven't quite yet learned
218
00:11:24,430 --> 00:11:27,600
how we can render lists of data dynamically
219
00:11:28,460 --> 00:11:29,900
and therefore for the moment,
220
00:11:29,900 --> 00:11:32,620
I will not update the expenses array,
221
00:11:32,620 --> 00:11:34,520
that is something we'll do
222
00:11:34,520 --> 00:11:37,460
and learn about in the next course section though.
223
00:11:37,460 --> 00:11:41,380
For the moment, I just wanna confirm that the data arrived.
224
00:11:41,380 --> 00:11:44,040
So here's the function now again,
225
00:11:44,040 --> 00:11:46,350
using the same pattern as before,
226
00:11:46,350 --> 00:11:50,250
we can pass a pointer at this function to a new expense
227
00:11:50,250 --> 00:11:51,840
so that inside of new expense,
228
00:11:51,840 --> 00:11:55,160
we can call this function and pass that expense data
229
00:11:55,160 --> 00:11:56,933
up to the app component.
230
00:11:57,800 --> 00:12:01,220
So we could name this prop here on add expense,
231
00:12:01,220 --> 00:12:04,000
again, the name is up to you, it's your component
232
00:12:04,000 --> 00:12:06,440
but again, I will follow this convention
233
00:12:06,440 --> 00:12:08,533
starting with on to make it clear
234
00:12:08,533 --> 00:12:10,180
that it's a function pointer
235
00:12:10,180 --> 00:12:11,790
which has passed as our argument
236
00:12:12,660 --> 00:12:16,080
and then I pass a pointer at add expense handler
237
00:12:16,080 --> 00:12:19,923
to the on expense prop on new expense,
238
00:12:21,400 --> 00:12:25,310
and therefore inside of new expense, we can now call it.
239
00:12:25,310 --> 00:12:28,350
We can accept the props argument here as well,
240
00:12:28,350 --> 00:12:32,570
this parameter and in safe expense data handler
241
00:12:32,570 --> 00:12:35,220
which itself is called when something happens
242
00:12:35,220 --> 00:12:37,710
in the expense form, we can of course
243
00:12:37,710 --> 00:12:42,710
now also called props on add expense
244
00:12:43,770 --> 00:12:46,120
and of course here, we wanna use the name
245
00:12:46,120 --> 00:12:48,620
which we chose here in the app component.
246
00:12:48,620 --> 00:12:51,550
We're calling the function past as a value
247
00:12:51,550 --> 00:12:53,593
for that on add expense prop.
248
00:12:54,500 --> 00:12:57,520
I'm calling us here, and it will forward
249
00:12:57,520 --> 00:13:00,073
my enriched expense data here.
250
00:13:01,650 --> 00:13:03,660
And if we now save everything,
251
00:13:03,660 --> 00:13:08,410
again if I reload, and I add a book here for 1299,
252
00:13:10,930 --> 00:13:13,340
if I click add expense, this is being logged
253
00:13:13,340 --> 00:13:16,590
from inside the app component as we can clearly tell
254
00:13:16,590 --> 00:13:20,410
and I'm actually logging the expenses as I see,
255
00:13:20,410 --> 00:13:22,960
I wanted to log the expense instead,
256
00:13:22,960 --> 00:13:24,363
so let me fix this.
257
00:13:25,920 --> 00:13:29,960
Let me give this another try, a book 1299,
258
00:13:29,960 --> 00:13:34,960
pick a date, yeah, so now we're logging the single expense.
259
00:13:35,290 --> 00:13:37,240
Again, we'll use that expense
260
00:13:37,240 --> 00:13:40,690
and change the array and output DRA dynamically too,
261
00:13:40,690 --> 00:13:43,140
we'll do that in the next course section
262
00:13:43,140 --> 00:13:45,570
but for the moment I wanted to focus
263
00:13:45,570 --> 00:13:48,410
on that state and event handling thing
264
00:13:48,410 --> 00:13:53,230
and being able to pass data up is a crucial part of it
265
00:13:53,230 --> 00:13:54,763
and here's how it works.
21230
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.