Afrikaans
Akan
Albanian
Amharic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Instructor: Now with the changes we made
over the last lectures,
we are able to gather our expense data,
our user input and combine it into this object
and clear the form thereafter.
The only problem is that having this data is nice
but we technically don't need it
in the expense form component, do we?
in the expense form component, do we?
Instead we needed in the new expense
or to be precise in the app JS component even
or to be precise in the app JS component even
because there we have our expenses array
and ultimately our goal will be to add this new expense
which the user entered to this list of existing expenses
which the user entered to this list of existing expenses
and we probably also wanna enrich it by adding an ID.
So, we need to pass the data which we're collecting
and generating in expense form to the app component.
Now I put as point, we only learned
how we can pass data down.
So how we can, for example, in the expenses folder
pass title, amount and date from the expenses component
pass title, amount and date from the expenses component
to the expense items component.
So from parent to child, that's something we learned.
We can do that with props,
but how can we do it in the other direction
but how can we do it in the other direction
if data is generated in the expense form
and we then wanna pass it up to the app component?
Well, actually we already saw how it works
but it's easy to miss it.
So let me show it to you again.
So let me show it to you again.
In expense form, we are listening to user input
to change this to the title input, for example
and whenever the user types here,
this function title change handler executes
this function title change handler executes
and there we get this default event object,
that's something the browser gives us.
that's something the browser gives us.
Now, actually we can think about this input element here
as a component as well.
It's not one of our components
but it is simply a pre-built component,
we could say, provided to us by react
and of course translate it to the input Dom element
but it has this component character in the end
but it has this component character in the end
and we do also set some props on that component
including this special onchange prop.
Now, actually this onchange prop isn't that special,
it's just a prop named onchange
which wants a function as a value
which wants a function as a value
and then internally the input element
adds this event listener.
So react basically sees that we set a value
on this onchange prop and adds that listener
on the rendered input element.
But that is a pattern we can replicate
for our own components as well.
for our own components as well.
We can create our own event props,
if we wanna call it like, and we can expect functions
as values and that would allow us
to pass a function from a parent component
to a child component and then call that function
to a child component and then call that function
inside of the child component.
And when we then call a function,
we can of course pass data to that function as a parameter
and that's how we can communicate up from child to parent.
and that's how we can communicate up from child to parent.
Now, in case this was too quick,
let me simply show it to you.
Let's say we wanna pass the expense data
which we gather in the expense form component
which we gather in the expense form component
to the new expense component as a first step
because if we ultimately wanna reach the app component,
because if we ultimately wanna reach the app component,
we first of all have to reach the new expense component
because it's the new expense component
which uses the expense form
which uses the expense form
and then in a second step later, it's the app component
which use the new expense component
which use the new expense component
but we can't skip components in between,
that's also something you learned
in the previous course section.
Props can only be passed from parent to child,
we can't skip intermediate components.
So therefore as a first step,
let's make sure we can pass the expense data to new expense
let's make sure we can pass the expense data to new expense
and we can do it as by adding a new prop to expense form.
It's our components, so we can name it however we want,
but I will name it on save expense data,
but the name is totally up to you,
I'm just naming it on something
because I wanna make it clear
that the value for this prop should be a function,
that the value for this prop should be a function,
a function which will eventually be triggered
when something happens inside of this component.
In this case, when the user saves the entered expense data,
so when the form is submitted in the end.
so that's again a convention I'm following,
you don't have to name it like this,
you can name it however you want,
It's totally up to you.
It doesn't have to start with on.
It doesn't have to start with on.
I just do start with on to follow this convention
and to make it clear that the value for this prop
should be a function which can then be called
inside of the expense form component.
Hence, it's a function we should define here in new expense
Hence, it's a function we should define here in new expense
just as we did it for the input elements
with the functions we bound to the onchange prop,
we define those in the expense form
before we returned the JS Xcode as well.
before we returned the JS Xcode as well.
Now we're doing the same here one level above that
in the new expense component
for our own custom expense form component.
So here I'll add a const save expense data handler
and important as a parameter here,
I will expect the entered expense data.
The name of the parameter is up to you, it's your function
but now I make it clear that this function expects
to get this parameter.
And then here we can add our expense data
another object, copy in the entered expense data
another object, copy in the entered expense data
which I expect to be that object
which we generate here into submit handler,
so this object, I pull out all the key value pairs
and add them to this new object
and then I add in a new key, the ID key
and simply set that to math random.
Math random to string to convert it to a string.
Math random to string to convert it to a string.
It's not a perfect unique ID,
theoretically we could generate the same value twice
but it's good enough for this demo.
And then we can see what we do with that thereafter,
for the moment I'll just log does enriched expense data.
Now it's a pointer at this function,
which I wanna pass as a value to all onSave expense data,
so that this onSave expense data prop
in my custom component receives this function as a value.
in my custom component receives this function as a value.
Again, I don't execute it here,
we don't add parenthesis,
I just point at the function,
so that the function itself a pointer edit
is passed to expense form.
Now that's the first step.
The second step now is to use this function
inside of our custom component.
That's a step we didn't have to do for the inputs
because these are built in components basically,
because these are built in components basically,
but they're also we pass a function to onchange
and internally react and we'll add a listener
and call this function which we pass in
whenever that event occurs, that change event.
Now, since we're doing this on our own custom component,
we also have to call the passed in function manually
and that's what I'll do next.
and that's what I'll do next.
So inside of expense form, we now can expect this
onSave expense data prop because I am setting it
when I used the expense form component,
when I used the expense form component,
hence instead of expense form,
we can extract the value passed
for this prop ie, this function.
So, inside of expense form,
I of course now expect to get some props
because we're setting a prop now
because we're setting a prop now
and now, inside of the submit handler,
instead of I logging my expense data,
I will access props onSave expense data and execute it here.
And that's now important,
now I execute it.
I can execute it because the value which we get on this
onSave expense data key will be a function.
We are passing in a function here after all.
So it's this function defined in the new expense component
which we will now execute in a different component,
inside of expense form to be precise.
inside of expense form to be precise.
And we can execute the function
even though it's not defined inside of expense form
because we are passing a pointer at it
through the onSave expense data prop.
through the onSave expense data prop.
And this is a super important pattern
which you will use a lot in react.
This is how you can communicate between components
and how you can communicate up,
and how you can communicate up,
how you can make sure that a child component,
the expense form component here for example,
can communicate up to the parent component,
the new expense component in this case.
the new expense component in this case.
We can call a function in the new expense component
and we can pass data as a parameter.
and we can pass data as a parameter.
So here, when we call onSave expense data
in the expense form, I can pass the expense data
which are generated here as our argument
and that's the value which we'll receive
as a parameter here in new expense.
as a parameter here in new expense.
I hope this flow is clear.
The trick really is that we pass around
a pointer at a function.
Now, if we go back and I reload,
if I again, enter something here
and pick a date if I click add expense,
and pick a date if I click add expense,
you see this is being locked to the console
and it's being locked from the new expense file line 12,
so it's does log here.
so it's does log here.
And we can tell that it's from there
because we also have an ID field there
which has this random number
which has generated and converted to a string.
which has generated and converted to a string.
And that's how we can communicate up
and this is a super important pattern.
Now, of course, we can continue in this chain now
and we can communicate up from inside new expense to app
and we can communicate up from inside new expense to app
because it's this app component which needs
the new expense in the end to add it to this expenses array.
So therefore again, in app JS,
we can add a function which we defined
before we return JSX code
before we return JSX code
and we can simply name this at expense handler
and be expect to get our expense here as a parameter
and be expect to get our expense here as a parameter
and then we do something with it.
and then we do something with it.
And for the moment I'll just console log in app JS
and console log the expense
because we haven't quite yet learned
how we can render lists of data dynamically
and therefore for the moment,
I will not update the expenses array,
that is something we'll do
and learn about in the next course section though.
For the moment, I just wanna confirm that the data arrived.
For the moment, I just wanna confirm that the data arrived.
So here's the function now again,
using the same pattern as before,
we can pass a pointer at this function to a new expense
we can pass a pointer at this function to a new expense
so that inside of new expense,
we can call this function and pass that expense data
up to the app component.
So we could name this prop here on add expense,
again, the name is up to you, it's your component
but again, I will follow this convention
starting with on to make it clear
that it's a function pointer
which has passed as our argument
and then I pass a pointer at add expense handler
to the on expense prop on new expense,
and therefore inside of new expense, we can now call it.
We can accept the props argument here as well,
this parameter and in safe expense data handler
this parameter and in safe expense data handler
which itself is called when something happens
in the expense form, we can of course
in the expense form, we can of course
now also called props on add expense
and of course here, we wanna use the name
which we chose here in the app component.
We're calling the function past as a value
for that on add expense prop.
I'm calling us here, and it will forward
my enriched expense data here.
And if we now save everything,
again if I reload, and I add a book here for 1299,
if I click add expense, this is being logged
from inside the app component as we can clearly tell
and I'm actually logging the expenses as I see,
I wanted to log the expense instead,
so let me fix this.
Let me give this another try, a book 1299,
pick a date, yeah, so now we're logging the single expense.
Again, we'll use that expense
and change the array and output DRA dynamically too,
we'll do that in the next course section
but for the moment I wanted to focus
on that state and event handling thing
and being able to pass data up is a crucial part of it
and here's how it works.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.