JSX Walk-Through: Pet Details, Part 2



All you have left is to create a list of owners with links.

Petrack component analysis
Petrack component analysis

You’re almost done. Now, you get to handle a collection of data from the owners.

Stub out the owners list component

You’ve done this four other times, so it’s pretty straight forward.

// 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.

Petrack with owners headline
Petrack with owners headline

Dealing with the list

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.

const OwnersList = props =>
  <>
    <h2>Owners</h2>
    <ul>
      {/* Create li elements here */}
    </ul>
  </>
;

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!

Petrack with owners list and key error
Petrack with owners list and key error

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:

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!

What you’ve done, here

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.

What you’ve done, overall

You have used JSX to do some amazing things, here.


All you have left is to create a list of owners with links.

Petrack component analysis
Petrack component analysis

You’re almost done. Now, you get to handle a collection of data from the owners.

Stub out the owners list component

You’ve done this four other times, so it’s pretty straight forward.

// 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.

Petrack with owners headline
Petrack with owners headline

Dealing with the list

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.

const OwnersList = props =>
  <>
    <h2>Owners</h2>
    <ul>
      {/* Create li elements here */}
    </ul>
  </>
;

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!

Petrack with owners list and key error
Petrack with owners list and key error

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:

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!

What you’ve done, here

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.

What you’ve done, overall

You have used JSX to do some amazing things, here.