Published
- 6 min read
How To Map an Array of Objects in React
Let’s suppose you have an array of numbers and you want an array with the squares of those numbers.
It may look something like this:
- What we have - [1, 2, 3]
- What we want - [1, 4, 9]
We can use forEach for this use case like this:
const numArray = [1, 2, 3]
const squaresNumArray = []
numArray.forEach((num) => squaresNumArray.push(num * num))
While using forEach gets our job done, we do have to loop over the elements and create a new array to push the squared numbers.
If there are complex objects involved this might get a bit ugly and confusing.
It would become repetitive to create a new array and push the elements into it for every transformed array that we need.
To avoid the repetitveness of the operations involved i.e. creating a new array and pushing the elements into it we can use map.
Map is a function available for arrays just like forEach.
It takes a callback function as an argument, runs that callback function for every element in the array and returns a brand new array.
That way you avoid the process of looping over each element and pushing the element in the new array manually. The map function does that automatically for you.
Let’s have a look at how we can use map for arrays.
This is what the callback function will look like for map:
Using arrow function:
;(num) => num * num
Using function keyword:
function(num) {
return num * num;
}
Both of the above functions take an argument and return the result of the square operation.
Using the arrow callback function with map we would have something like this:
const squaresNumArray = numArray.map((num) => num * num)
The map function will run the callback function for every element in the array and return a new array and the old array will remain unchanged.
We can confirm this by console logging both of the arrays.
console.log(numArray)
// Output:
// [1, 2, 3]
console.log(squareNumArray)
// Output:
// [1, 4, 9]
Please note that it is important to return something from the callback function for it to push the result into the new array. Not returning anything from the callback function might give you unexpected results.
Now let’s see how to use map for arrays of objects.
How to use map for an array of objects
Let’s take up another example where we have an array of objects like:
const firstAndLastNamesArray = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Mary', lastName: 'Ann' }
]
Let’s say that we want to change this array to:
const namesArray = [{ name: 'John Doe' }, { name: 'Mary Ann' }]
We can pass a callback function to map which will concatenate first and last names from the firstAndLastNamesArray and add it to the namesArray.
The callback function will look something like:
;(namesObj) => ({ name: namesObj.firstName + ' ' + namesObj.lastName })
The callback function gets the individual elements from the firstAndLastNamesArray and creates a new object with name as the key and value as the concatenated first and last names.
The brand new object is then returned to push it to a new array.
Using the above callback function with map we get:
const namesArray = firstAndLastNamesArray.map((namesObj) => ({
name: namesObj.firstName + ' ' + namesObj.lastName
}))
The namesArray will be a new array containing the concatenated names objects while the firstAndLastNamesArray will remain as it is.
console.log(firstAndLastNamesArray)
// Output:
// [
// {firstName: 'John', lastName: 'Doe'},
// {firstName: 'Mary', lastName: 'Ann'}
// ]
console.log(namesArray)
// Output:
// [
// {name: 'John Doe'},
// {name: 'Mary Ann'}
// ]
How to render an array of objects in React
Continuing with the above example, let’s say that we want to render the namesArray as a list in React.
We can pass a callback function which returns some astro like:
;(nameObj) => <li>{nameObj.name}</li>
The callback function will get the individual elements of the namesArray as an argument.
It will then embed the value of the name key between the list tags and return the astro.
If we use the above callback function with map, we will have:
const mappedNames = namesArray.map((nameObj) => <li>{nameObj.name}</li>)
mappedNames will be a new array containing the astro with names and the namesArray will remain untouched.
You can then render mappedNames in React like:
<ul>{mappedNames}</ul>
How to use map for an array inside an object in React
Let’s move the above example up by a notch and let’s say we have the following response being returned from an API:
const response = {
totalCount: 2,
userNames: [
{ id: 256, firstName: 'John', lastName: 'Doe' },
{ id: 678, firstName: 'Mary', lastName: 'Ann' }
]
}
Suppose we want to render the userNames array as a list in React.
Let’s see how to go about that.
The callback function would look something like:
;(userName) => <li>{userName.firstName + ' ' + userName.lastName}</li>
The callback function gets the userName object which has the first and last names of the user and returns the names embedded in the list astro tags.
We can then plug the above callback function into our map function like:
const names = response.userNames.map((userName) => (
<li>{userName.firstName + ' ' + userName.lastName}</li>
))
We can then render the names like:
<ul>{names}</ul>
What is the key prop and why does it matter
If you are using the map function for arrays in React you might have noticed that you get a warning like:
Warning: Each child in a list should have a unique “key” prop.
You get that warning because React expects you to provide a key for every item that you return from the map function.
Consider our previous example,
const names = response.userNames.map((userName) => (
<li>{userName.firstName + ' ' + userName.lastName}</li>
))
;<ul>{names}</ul>
Consider another sample, where we are also displaying a list of elements but not using map.
<ul>
<li>John Doe</li>
<li>Mary Ann</li>
</ul>
We might get the same output in terms of HTML but the difference in the second example is that we are not rendering an array.
What you see on the screen is the same output but how React handles it internally is different.
If you are rendering an array of elements then React does not know if you added or removed the element from the beginning, middle or end.
It guesses the element to add or remove using the index value of the element by default.
In simple scenarios it does not cause much of a disruption and React does what we expect.
But what if we have complex components being rendered which internally manage their own states as well?
If React is made to work on best cases for such complex scenarios then it might lead to unexpected results.
That’s why it’s important to add a key prop so that React knows which element exactly was removed or added alongwith its position in the list.
React then knows how to move the other elements in the list once a new element is added or an older one is removed.
Takeaway
Maps are mainly used to transform a given array into a new array containing the transformed values.
In React, map is used to render lists of elements.It also becomes important then to add a key prop to the list items so that React knows how to manipulate the list when the list elements are removed or if new ones are being added.
I hope that this article has provided you with some clarity on how to use the map function in React.
If you have any questions or comments, please feel free to add them in the comments section.
Till then,
Happy Coding!