- In this section,
we are going to investigate an application
with multiple components.
This will help you to understand
how to define multiple components and why,
and how to pass parameters into them
so that they know what to display.
Remember, a component is either a function or a class
which renders some HTML.
So in a typical application,
you will have one top level component called App,
which basically is the whole web interface,
and it then calls smaller components
to display part of the webpage.
A bit like the way the main function calls smaller functions
in Java and C#.
So we'll have one top level component,
the root component called App,
and it will then render lower level components,
each component renders part of the webpage.
And it needs parameters to help it know what data to display
in those components.
So our app will demonstrate
how to define a root component called App.
You nearly always, in a React application,
define a top level root component.
You know, the first component to be rendered,
like the main function in a Java application
and you typically call it App by convention.
It then calls other lower level components
to render part of the webpage for the whole
React application.
You don't...
The application component couldn't possibly
render everything because it's too complicated.
What you do instead is the App component
cause other components and they display part of the webpage
each.
It's divide and conquer.
We can pass parameters into a component to say
I want to invoke this component,
it needs to render some content
or here's the parameters, here's the data that you need
in order to decide what to display,
We're gonna work with...
Well, it's not gonna be that complex data,
but as we go through the examples,
it'll be the data that we pass
or that we render would become increasingly interesting,
as you'll see.
So I've already written this example.
If you look in the Example 3 folder,
you can see the application.
So here we are, Lesson 9, Example 3,
I used to create React App tool
to create this demo application.
And it has the same structure as every other application
generated using Create React App.
So let's have a look at this application
in the code editor here.
Here it is.
It has a Package Jason file
which specifies the dependencies.
When you create the application,
it downloads those dependencies, as we've seen,
into node models.
In the public folder, the only thing of interest really is
the index HTML, our homepage.
I've tided it up a little bit.
Again, it's this bit here, the outlet.
Basically, all of my content
for the entire React application will be displayed here
- Right. In the source folder then,
this is a bit more interesting than what we've seen before.
I have defined...
Well, first of all, you always start...
The application always starts with index.tsx.
And in 99 times over a hundred,
the index tsx simply renders the application component,
okay, to say, start.
The application component is here, Apptsx.
Notice, I've got rid of some unnecessary files.
When you generate this application,
there'll be an app test and an app CSS.
So I've deleted those
because we don't really need them in this example.
So this is a top level component.
And what is it going to display?
Okay, well, it's going to display...
Ignore the React fragment bit for now.
Okay. That's just like a wrapper.
It's going to render another component.
This is how one component can say,
please, can you render another component?
Panel A is another component.
Or to put it another way,
it's a function that returns some HTML XML.
We'll have a look at that there.
In fact, I've got four components
growing in interest and complexity as we work through them.
Panel A displays a div, which is quite simple.
So does Panel B, so does Panel C, and panel D
but with parameters as we'll see.
Okay. So I think probably we should have a look
at how this application's gonna look
before we dive into the code.
So to run the application, you say, yarn start
or you can say, NPM start.
Well, I've done that already.
I've already started the server
and it'll host my application
and this is what it looks like.
That's how it's going to appear in the browser.
So it displays Panel A...
Oh, I've got some colors. I hope you like them.
I spent quite a while choosing them.
Panel A decides to display itself in blue,
Panel B decides to display itself in green.
Now I have three instances of Panel C.
Panel C is a component.
It's ultimately a function,
but if you render it three times,
then that's the panel three component.
The same function called three times,
it calls, it displays itself three times.
And then I've got another component called panel D
which is a little bit more ambitious in that
it kind of has more interesting content.
Okay. So Panel A, Panel B, Panel C and Panel D.
Those are the four components that are rendered
by my application component.
So just take you back to the top again,
here's my application component, app.tsx.
It renders a component, Panel B, with some parameters.
It rendered three instances.
In fact, four.
Three, that's right.
(Narrator chuckles) I can't count.
Three instances of Panel C.
It basically called the Panel C component three times.
It calls the function three times.
It displays itself three times illustrating different syntax
and then, it renders panel D.
So each of these, Panel A, B, C, and D,
each of those is a separate component defined.
Typically, you put each component into a separate file.
Panel A.TSX.
Panel B.TSX, Panel C and Panel D.
Okay, then, so that's Panel A TSX.
It's a really simple functional component.
The function is called Panel A and it returns a div.
I've got some CSS classes involved.
I've got a class that says
if you have a div whose CSS class is Panel A,
then it displays it in blue.
I think it was, wasn't it?
And it says hello from Panel A component.
Let's have a quick look at that
in the actual code deck, Panel A.tsx.
So I'm just wondering about the style.
There's an interesting thing here.
In normal HTML,
if you want to set the CSS class for something,
you would just say class.
But unfortunately, in JavaScript these days,
class is a keyword.
That's a bit of a shame.
So in React, you've gotta say class name.
In your React code, you say class name.
When it gets compiled by Babel,
it converts it into a, like a regular CSS class attribute.
But so the question I've got for you is, okay
so that's very well, that's what my panel will display.
And remember,
here's my top level component that says,
please, will you render panel A.
And it says, okay, then I will.
But where does this CSS class come from
because I haven't imported any style sheet here?
So I guess, it must be the style sheet that sits
across the whole application.
Remember, in the top level code file index,
it imports the kind of corporate global style sheet.
So I guess, the classes must be defined in there
and they are.
So in here, I've said like, first of all,
I think I could probably...
I think I'll probably get rid of that line,
but you can see, at any div with a class
of either Panel A, B, C, or D, they get displayed
with a white font and a certain size.
A class... Sorry, a div with a Panel A class
would be displayed in blue.
Well, that's good.
Here's my Panel A class, here's my panel A component.
It displays in a CSS class of panel A,
and that class is going to be blue.
So my Panel A gets displayed in blue.
That's very good.
So there we are.
Here's my functional component,
and here's how I invoke it.
It is confusing initially.
It is a function
but you don't call it like a function.
There are reasons for this that are kind of
beyond what we're looking at just now.
You use XML syntax.
Effectively, it almost like it creates an object
from this function to represent this markup.
We can think of it more loosely and say
it's almost like a function call to render that content
plus some other content.
Well, what came next was Panel B,
and it turns out that Panel B has a parameter.
So here's a statement of fact, if a component needs inputs,
your component can receive one object.
It works like that.
Your component can receive one object
that contains properties.
There may be many properties inside the object
but it is just one object.
And in type script, you have to say call on any
just to keep the type script compiler happy to say,
okay, I'm not gonna bother telling you what the data type is
but that's fine.
Let me show you how I call it.
If you have a component that takes property parameters,
you just declare them as normal XML attributes like this.
And what actually happens is those properties
or these attributes that you specify here,
those attributes get plated into an object.
Okay? So I've only got one parameter at the moment.
The parameter is called Message and the value is, Hello.
Okay. Hopefully you can read my writing.
So this attribute gets placed into an object,
and that object then gets passed in as a parameter
into the functional component.
It always works like that.
No matter how many parameters you pass in,
it'll just be one object that's received.
So inside my Panel B,
I take that incoming object and I grab the message property.
Okay. So that would be hello,
and I just assign it into a local variable
just to make my life easier.
So message, MSG message is hello.
That's the message parameter placed into an object,
and then I grab it out of there,
I assign it to that local variable.
And then here,
I say hello from Panel B component with message, message.
There's a bit of syntax here that I haven't explained before
when you've got JSX syntax, with a of JavaScript and XML,
when you're in the middle of XML syntax,
like an XML element,
if you want to evaluate any JavaScript expressions
like the value of the message variable,
you have to enclose this JavaScript inside curly brackets.
Okay. If you didn't put the curly brackets in there,
it would just kind of...
If you didn't put the curly brackets in there,
it would just literally display the word MSG.
It's the curly brackets that make it realize
it has to evaluate it.
I'll prove that point.
I'm gonna go into my Panel B component.
And what I'll do is I'll accidentally on purpose
forget to put that inside curly brackets.
Okay. So then instead of evaluating, you know,
the value of the message variable,
it'll just literally display the text MSG
which isn't probably what I had in mind.
Okay. So don't forget the curly brackets
when you want to evaluate JavaScript.
Now, this panel just receives one parameter
but of course, you can pass in multiple parameters
if you like.
Have a look at this.
Panel C takes in two parameters.
They always get passed in as a single object though.
So a single object gets accumulated,
these parameters, these XML attributes get accumulated
into a single object.
So there'll be a property called F name, first name.
And the first name is Kari.
Okay, good.
And then the L name,
the person's last name is Nordmann.
Nordmann, like so.
So that object again gets passed
into the component as a single object, like, so.
And then from that object,
I extract the first name property, Kari,
and I put into that variable so I can display
the person's first name.
And then from the object, I called it props,
but I could have called it anything,
I extract the last name property, which would be Nordmann,
I put it into another help available,
which I can then display there. Okay?
So it says hello from Panel C component
with the first name of Kari and the last name of Nordmann.
So that's fair enough I think, isn't it?
I'm gonna show you some alternative syntax
using destructuring.
Let me go back into my code.
If you remember, destructuring is the ability to
take an object and to extract its properties easily.
So I'm gonna give myself a bit of blank line.
Instead of declaring separate variables like this,
I could have done it in a single statement like this,
using destructuring { fname, lname
= props.
Oops. = props.
Okay. So those two lines, I can now comment out,
this line is equivalent to these two lines.
It'll say, take the object and form that object,
look for a property called Fname
and stick it into a variable also called Fname.
Okay. So there's that correspondence of names there,
Fname.
And also extract the Lname property
and put it into a variable called Lname.
Well, that'll do the same.
So we de structure the incoming object
and grab the constituent parts and put them into variables
called Fname and Lname.
That's pretty cool.
I'll just save that,
and I'll prove that it still actually works.
It has the benefit they're still working.
Okay. So that's still looking good.
That was this example here.
And to take it a step further,
instead of doing the destructuring here inside the function,
you can actually use destructuring syntax directly
in the function parameter.
The function receives one object,
you can de structure that incoming object like this,
extract the Fname property into that variable
and extract the Lname property into that.
Okay. And then I can get rid of this statement.
I've effectively done it in line.
So what this means is... Or and because it's type script,
you need to just say, "Oh, I'm not gonna bother fussing
about what types they are, anything will do."
So these properties get passed in
from my main application component.
When it passes in an Fname property and an Lname,
those get passed into an object.
That object is destructured.
The Fname property is extracted into this variable
and the Lname into that variable.
And that means, we don't need to do any kind of explicit
extraction here.
We can just use the variables that have already
been extracted, like so, okay?
So that's a really common technique in React.
Okay. What's next?
Let's have a look at this example here.
What I've done here is instead of hard copying it,
I've got an object, okay.
Typically, you have an object that contains some data.
So this object, you know,
it might have come from a rest service call.
So you've actually got an object here, a person,
and the person's first name is Kari,
and the person's last name is Nordmann.
And the sent backs I've got here is kind of similar
to the previous slide,
grab the person's first name, Kari,
and pass it in as the Fname parameter.
So the same thing's gonna happen.
An object will get created.
It'll have an Fname property,
and the Fname property will be the person's first name Kari,
I'll just write K for Kari,
and then I'll pass into the object, an L name property,
L name, and the L name property is going to be
the person's last name, which is Nordmann.
I'll just write N.
Okay. So an object, I grab the properties,
pass them in as properties called that and that,
the object gets passed into my component.
My component can then access the person's first name
and the person's last name like that.
Okay. So basically, it's very similar,
the only difference between this and the previous example
is that the data came from an object beforehand.
One last example, here
you can also use the spread operator.
The spread operator will automatically expand
an object into its constituent parts.
So when you say ...person,
this is equivalent to say, right,
invoke the Panel C component, Panel C,
expand all the properties in the person object.
So in other words,
it'll basically expand it into Fname = Kari,
I'll just write K for Kari.
And it'll also expand the Lname property.
The.... syntax basically just expands all the properties
one by one.
So it's easier.
It's easier for you to expand the object using that syntax.
It'll automatically generate an Fname property
and then Lname property, like so, okay.
And then, once you've done that,
those properties will then get bundled into an object
and passed up into my component
in the same way that we've been looking at.
Okay. So the spread operator is the easiest way
to pass an entire object into another component.
Right. Almost done.
Panel D, have a look at this one.
I've got a rich data type here.
An employee has a name and a salary and some skills.
This person can do Spring Boot, React, and type script.
Pass all of those properties up into the component.
Okay. So using the spread operator here,
again, it'll create an object,
and that object will basically have a name property,
the employee's name.
The employee's name, Jane Doe.
Okay, good.
There'll be a salary property.
How much does Jane earn?
Jane earns 20 K, not bad.
And there's skills property, skills.
Skills is an array of strings.
I'll draw that like this, as an array.
Okay. So those properties get bundled into an object.
That object is then passed into the component,
and the component uses that destructuring syntax.
It says, grab the name into that variable
that would be Jane Doe.
Extract the salary, 20 K,
and extract the skills.
The skills remember is that array that looks like this.
And then, it outputs the name Jane Doe, and the salary.
And then what it does is it uses a map function.
This is a really common technique.
I've got an unordered list here,
I'll remind you what it looks like.
This is what it's gonna look like.
It takes the strings of the person's skills
and it converts each string into a list item like that,
using array map.
It takes skills, which is the array,
and it passes...
It calls the map function.
When you call the map function on an array,
it'll call, I've specified here, effectively,
an arrow function that starts there and ends there.
This is an arrow function,
and it's gonna call that arrow function for each element.
So the first one, it basically passed in the first skill.
Okay.
The first skill will be in Spring Boot
and the index is the zero, basically.
And then in here, it outputs,
it basically takes that skill, Spring Boot
and it converts it into a list item.
Ignore the key attribute for now,
that's just a React mechanism.
It outputs the skill, Spring Booth.
Don't forget curly brackets
when you have JavaScript in the middle of a list,
and then enlist item.
So it took in that text, Spring Boot,
and it converted it into a list item like that.
Okay.
The whole thing is enclosed in an unordered list.
So I guess what I could do, I'm gonna go back into my code.
I'm gonna modify my map function.
I'm gonna, first of all,
slightly rearrange the indentation
to see if that makes it look easier on the eye.
I'm quite fussy with my code, I don't know about you,
but I spend quite a lot of time fussing about my code
to make sure that it's as readable as possibly could be.
Right. So I have an unordered list.
I'm gonna change that to be an ordered list, OL.
OL.
Okay. Remember, whenever you change your code here,
React automatically refreshes the browser.
So I should now have an ordered list and it is ordered.
And what I'm gonna do is I'm going to take each skill,
I'm gonna rename this variable.
Generally, when you've got Lambdas,
you wanna give these variables short names.
I'll just call it S, S for skill.
And it'll take the skill and the index number,
and it'll display a list item with a key.
The key is just there to react, like each element in a list
to have a different ID number.
And I'm gonna put the skill in uppercase.
Okay. Because it is a string,
I can convert it in uppercase.
Okay. So basically, the string that came in
was like Spring Boot, and it'll display Spring Boot
in a list item in capital letters.
There we go.
All right. So it's really quite a useful thing.
You often have arrays in React,
and you typically take the array of data
and you map each piece of data into an element.
And that element gets displayed
as a larger part of your output.
And remember, remember to put code inside curly brackets.
If you forgot the curly brackets,
it would just output the text, literally,
which wouldn't be so pleasing for the user.
Okay. Now, instead of actually displaying the value,
it just displayed, oh, the code.
So you'd probably get a G-reel report if you did that.
So let's just fix it,
and let's put the curly brackets back in again, there we go.
And the user interface, lovely.
So that's quite a realistic example.
Just to summarize, we have an application component,
and the application component calls other components,
and each other component can have parameters
to basically decide what to render.
You can pass the parameters in, in many different ways.
And when the component receives it, it can use techniques
like mapping to decide how to display it.
One final point which I hadn't mentioned before.
When you have a component, it returns XML,
it's gonna return a single outer element. Okay?
You can't return like sibling elements.
You have to have one element as a wrapper,
and that's what fragment React is.
It's like an invisible wrapper.
If I just left it like that,
it'll say, you can't return lots of elements side by side.
They have to be encapsulated
in a single element on the upside.
So you could write that.
These days, in modern React, you can just actually write it
like this, it looks a bit odd.
It's like an empty element.
It fulfills the purpose of being a wrapper.
It doesn't display anything,
it's just a sandwich with the meat in the middle.
There we go.
So I think it's quite nice.