Perhaps you are compiling an application for a community center, a gardening store, or need to display user information and that data is contained in an array. How do you render that data in React?
Below is an example of an array of objects that might be listed on a community site.
Example Array
const listings = [
{
"id": 1,
"description": "heater",
"image": "./images/heater.jpg"
},
{
"id": 2,
"description": "2019 Toyota Tacoma grill",
"image": "./images/toyota-grill.jpg"
},
{
"id": 4,
"description": "FREE Hundreds of DVD/CD Cases - Different Sizes and Colors",
"image": "./images/dvd-cases.jpg"
},
{
"id": 5,
"description": "wood",
"image": "./images/wood.jpg"
},
{
"id": 6,
"description": "Beautiful couch",
"image": "./images/couch.jpg"
},
{
"id": 7,
"description": "Treadmill Parts For Free",
"image": "./images/treadmill.jpg"
}
]
Ok, now that we have our data how are we going get on the UI? One way to do it is by using the map method. You may be familiar with this method from vanilla JavaScript. It creates a new array which is populated by executing whatever actions the callback function requests on each of the elements in calling array. The MDN documentation can be found here:(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
Here is an example of rendering data with Array.map() in React in the same functional component.
import React from "react";
import { listings } from "../data";
function ListingCard() {
const listingComponents= listings.map((listing) => (
<div key={listing.id}>
<h2>{listing.description}</h2>
<img src={listing.image} alt={listing.description}/>
</div>
))
return (
<div>
<h1>Free Stuff Page</h1>
{listingComponents}
</div>
)
}
export default ListingCard;
Here is our data rendered!
Ok let's talk a bit about the code.
We have an array of items (listings) that we want rendered on the Free Stuff Page of a local community app. We used the Array.map() method to render the listings data. This method loops through the array and gives you access to each item in the array in a callback function. In order to get your items rendered you will need to return the JSX elements you wish to see.
const listingComponents= listings.map((listing) => (
<div key={listing.id}>
<h2>{listing.description}</h2>
<img src={listing.image} alt={listing.description}/>
</div>
))
In the example above we are returning an h2 HTML element that displays a the description of the item and an img HTML element that displays a picture of the item with alternative text that is equal to the description. You may have noticed that both of these items are wrapped in a div HTML element, that is because all of the elements must be contained inside one JSX/HTML element so if you are returning multiple elements be sure to wrap them.
Additionally you may have noticed that we assigned a key that is not displayed and we don't seem to use again. When you are using Array.map() in React you must pass the key prop. React uses this key internally to keep track of items for multiple reasons. If don't pass one you will most likely get errors and risk some potentially suspect behaviors by React. Therefore, it is important that each item has a unique value for a key.
return (
<div>
<h1>Free Stuff Page</h1>
{listingComponents}
</div>
)
Finally, we passed our entire JSX element associated with the const listingComponents to the portion of the functional component being rendered. While we could have called .map() on the array inside the div that is holding our components to be rendered we did not in order to make our code easier to read and easier to debug if something goes wrong with that particular element. In this instance the application display is simple and so these are less likely to be issues but it's a good practice.
Another thing to note about the code, curly bracers { }.They are around both our listingComponents variable and the display items to be rendered that are returned from mapping our array. The curly braces are syntax to let the JSX parser know that it should understand that part as JavaScript.
Here is another example where we are performing Array.map() and then passing the results to another React component for destructuring and rendering:
import React from "react";
import PlantCard from "./PlantCard";
function PlantList({plants}) {
console.log(plants)
// sanity check and to make sure that our props
// are what we think they are
const plantCardComponents =plants.map((plantObj)=>{
return(
<PlantCard
key={plantObj.id}
name={plantObj.name}
image={plantObj.image}
price={plantObj.price}
/>
)
})
return (
<ul className="cards">
{plantCardComponents}
</ul>
);
}
export default PlantList;
Above we receive the prop of plants which is an array of objects that were fetched in the main React component App and passed to our PlantList component.
Then after executing Array.map() on plants we are passing the JSX component we created PlantCard with the key:value pairs of interest we want to have access to in the PlantCard component. Here our key:value pairs are all within PlantCard so we don't need to additionally wrap them in a div or another HTML/JSX element, like when creating multiple individual HTML elements as part of executing Array.map() in the first example for posting free stuff.
Next lets look at PlantCard which we passed our mapped array as the prop {plantCardComponents}. In this example, plantCardComponents has been destructured into component props so that we are only utilizing the values we assigned to image, name, and price. This helps cut down on repetitive code, limits the data we are passing about, and makes the below component easier to read/closer to DRY.
import React from "react";
function PlantCard({image, name, price}) {
return (
<li className="card">
<img src={image} alt={name} />
<h4>{name}</h4>
<p>Price: {price}</p>
</li>
);
}
export default PlantCard;
Here is our rendered data:
Thanks for reading this post! Good Luck in your React and .map() endeavors and Happy Coding!
Top comments (1)
A headsup on your
PlantCard
component... I wouldnt spread out the props on it like that, this means that if you change the name of a property in yourplantObj
, you have to change it everywhere you use thePlantCard
component. It's better to provide the entireplantObj
to yourPlantCard
component:That way if you decide to change the
plantObj
later, or if you want to use other properties that from it, you only have to change the code inside thePlantCard
component.