All you have left is to create a list of owners with links.
PetDetailPage
: DoneNavigation
: DonePetDetails
: Modified in this stepPetDetailList
: DonePetInformationItem
: DoneOwnersList
: Created in this stepOwnerLink
Created in this stepYou’re almost done. Now, you get to handle a collection of data from the owners.
You’ve done this four other times, so it’s pretty straight forward.
OwnersList
with a props
argument that uses a React.Fragment
as its elementdefaultProps
, add a default property value for “owners” and set it to an empty array because this component will expect an array of owner dataOwnersList
as the default exportOwnersList
componentPetDetailPage
component after the PetDetailList
PetDetailList
and OwnersList
in a Fragment
.OwnersList
component in a property named “owners” like this {props.pet.Owners}
which will pass in the array of owners for the pet// src/PetDetails.js
import React from 'react';
import OwnersList from './OwnersList';
import PetDetailList from './PetDetailList';
const PetDetails = props =>
<>
<PetDetailList pet={props.pet} />
<OwnersList owners={props.pet.Owners} />
</>
;
PetDetails.defaultProps = {
pet: {
PetType: {},
},
};
export default PetDetails;
Refresh the page and make sure everything still works.
Note: This section introduces an error that you will fix. It is a common error about how to create React elements from lists. You may see it often. This way, you will know how to fix it, too.
Back in OwnersList.js, you want a ul
to follow the h2
.
Here’s the thing. You have an array of owners. You want to turn them into some list items. For each owner, you want to map that to a list item. And, therein lies the hint. Since the value in props.owners
is an array, you can use the map
function to generate another array of React elements and plop them in there! Give it a go with this code. Replace the comment about where list items go above with this line of code.
{ props.owners.map(owner =>
<li>{owner.firstName}</li>
)}
Refresh the page. What happens? You should now see “Human” for each of the list items. That’s great! In the console, there’s an error. That’s sad!
In this last step, you’ve changed the way you’re passing children into the React.createElement
. Up until now, you’ve had discrete single elements as children, like in PetDetailList.js where you have this code.
const PetDetailList = props =>
<>
<h2>Details</h2>
<dl>
<PetInformationItem name="Name" value={props.pet.name}/>
<PetInformationItem name="Age" value={props.pet.age}/>
<PetInformationItem name="Type" value={props.pet.PetType.type}/>
</dl>
</>
;
Each of PetInformationItem
elements is a different, discrete, and separate child for the dl
element.
The code in OwnersList.js, this code,
const OwnersList = props =>
<>
<h2>Owners</h2>
<ul>
{props.owners.map(owner =>
<li>{owner.firstName}</li>
)}
</ul>
</>
;
in that, you have created an array of objects. Recall that when you call the map
function on an array, it returns another array. React doesn’t care about this, but it would like a little help in tracking each of those entries in the virtual DOM that it builds. That’s what the error message is about, giving React a little help by providing a “key” property for each of the elements that you’re creating in the array. The value of the “key” property must be unique and stable, that is, for a given object (like an owner named “Human One” with an id of 7), the value returned must always be the same. Luckily, because you have the id of the owner, you can use that because that id value is tied to a primary key, somewhere, and should never change for this object. The name can change, of course. But, the id will likely never change.
Add a “key” property to the li
element and set it equal to the id of the owner object, like this.
<li key={owner.id}>{owner.firstName}</li>
Now, the error in the console goes away.
Back to the OwnersList
component, look at the formatting, the indentation that you see in the code.
const OwnersList = props =>
<>
<h2>Owners</h2>
<ul>
{props.owners.map(owner =>
<li key={owner.id}>
{owner.firstName}
</li>
)}
</ul>
</>
;
That, too, is idiomatic React, the React way of doing things. You’ll see that kind of code all over the React world.
While it’s nice, and all, to see the owner’s first name in the list, the actual page has a link to the owner page with the format “last name, first name”. Time to create the (last!) component of this walk-through.
Create a new file named src/OwnerLink.js. In it, do the following:
OwnerLink
that accepts data that has
a
as its elementprops
Once you have that, import the OwnerLink
component into the src/OwnersList.js file. Now, replace this line in OwnersList
{owner.firstName}
with an OwnerLink
component with three attributes: “href”, “firstName”, and “lastName”. Those are the three properties expected inside the component. Use the curly brace syntax to pass in the appropriate values of the owner
. This is something you haven’t done, yet. Try to think through the problem of how to pass in multiple property values. If you get stuck and can’t get it after about ten minutes, ask for help!
Refresh the page. If everything works, you’re done!
In this part of the walk-through, you used a collection to render a collection of React elements. You found out that using a collection like that requires you to provide a “key” property that has a stable, unique value. Once you had that, React would gladly manage that collection of objects in its virtual DOM.
You have used JSX to do some amazing things, here.
React.createElement
<>
and </>
are shorthand literal for the often-used React.Fragment
elementdefaultProps
to make sure that components always had some valid values to work withAll you have left is to create a list of owners with links.
PetDetailPage
: DoneNavigation
: DonePetDetails
: Modified in this stepPetDetailList
: DonePetInformationItem
: DoneOwnersList
: Created in this stepOwnerLink
Created in this stepYou’re almost done. Now, you get to handle a collection of data from the owners.
You’ve done this four other times, so it’s pretty straight forward.
OwnersList
with a props
argument that uses a React.Fragment
as its elementdefaultProps
, add a default property value for “owners” and set it to an empty array because this component will expect an array of owner dataOwnersList
as the default exportOwnersList
componentPetDetailPage
component after the PetDetailList
PetDetailList
and OwnersList
in a Fragment
.OwnersList
component in a property named “owners” like this {props.pet.Owners}
which will pass in the array of owners for the pet// src/PetDetails.js
import React from 'react';
import OwnersList from './OwnersList';
import PetDetailList from './PetDetailList';
const PetDetails = props =>
<>
<PetDetailList pet={props.pet} />
<OwnersList owners={props.pet.Owners} />
</>
;
PetDetails.defaultProps = {
pet: {
PetType: {},
},
};
export default PetDetails;
Refresh the page and make sure everything still works.
Note: This section introduces an error that you will fix. It is a common error about how to create React elements from lists. You may see it often. This way, you will know how to fix it, too.
Back in OwnersList.js, you want a ul
to follow the h2
.
Here’s the thing. You have an array of owners. You want to turn them into some list items. For each owner, you want to map that to a list item. And, therein lies the hint. Since the value in props.owners
is an array, you can use the map
function to generate another array of React elements and plop them in there! Give it a go with this code. Replace the comment about where list items go above with this line of code.
{ props.owners.map(owner =>
<li>{owner.firstName}</li>
)}
Refresh the page. What happens? You should now see “Human” for each of the list items. That’s great! In the console, there’s an error. That’s sad!
In this last step, you’ve changed the way you’re passing children into the React.createElement
. Up until now, you’ve had discrete single elements as children, like in PetDetailList.js where you have this code.
const PetDetailList = props =>
<>
<h2>Details</h2>
<dl>
<PetInformationItem name="Name" value={props.pet.name}/>
<PetInformationItem name="Age" value={props.pet.age}/>
<PetInformationItem name="Type" value={props.pet.PetType.type}/>
</dl>
</>
;
Each of PetInformationItem
elements is a different, discrete, and separate child for the dl
element.
The code in OwnersList.js, this code,
const OwnersList = props =>
<>
<h2>Owners</h2>
<ul>
{props.owners.map(owner =>
<li>{owner.firstName}</li>
)}
</ul>
</>
;
in that, you have created an array of objects. Recall that when you call the map
function on an array, it returns another array. React doesn’t care about this, but it would like a little help in tracking each of those entries in the virtual DOM that it builds. That’s what the error message is about, giving React a little help by providing a “key” property for each of the elements that you’re creating in the array. The value of the “key” property must be unique and stable, that is, for a given object (like an owner named “Human One” with an id of 7), the value returned must always be the same. Luckily, because you have the id of the owner, you can use that because that id value is tied to a primary key, somewhere, and should never change for this object. The name can change, of course. But, the id will likely never change.
Add a “key” property to the li
element and set it equal to the id of the owner object, like this.
<li key={owner.id}>{owner.firstName}</li>
Now, the error in the console goes away.
Back to the OwnersList
component, look at the formatting, the indentation that you see in the code.
const OwnersList = props =>
<>
<h2>Owners</h2>
<ul>
{props.owners.map(owner =>
<li key={owner.id}>
{owner.firstName}
</li>
)}
</ul>
</>
;
That, too, is idiomatic React, the React way of doing things. You’ll see that kind of code all over the React world.
While it’s nice, and all, to see the owner’s first name in the list, the actual page has a link to the owner page with the format “last name, first name”. Time to create the (last!) component of this walk-through.
Create a new file named src/OwnerLink.js. In it, do the following:
OwnerLink
that accepts data that has
a
as its elementprops
Once you have that, import the OwnerLink
component into the src/OwnersList.js file. Now, replace this line in OwnersList
{owner.firstName}
with an OwnerLink
component with three attributes: “href”, “firstName”, and “lastName”. Those are the three properties expected inside the component. Use the curly brace syntax to pass in the appropriate values of the owner
. This is something you haven’t done, yet. Try to think through the problem of how to pass in multiple property values. If you get stuck and can’t get it after about ten minutes, ask for help!
Refresh the page. If everything works, you’re done!
In this part of the walk-through, you used a collection to render a collection of React elements. You found out that using a collection like that requires you to provide a “key” property that has a stable, unique value. Once you had that, React would gladly manage that collection of objects in its virtual DOM.
You have used JSX to do some amazing things, here.
React.createElement
<>
and </>
are shorthand literal for the often-used React.Fragment
elementdefaultProps
to make sure that components always had some valid values to work with