While traditional looping techniques such as while
loops or for
loops are still usable in React, developers have a unique tool at their disposal for looping through a wide variety of arrays and key-value pairs. This React tool is known as the map()
function.
In the post, I’ll be talking more about the map()
function – how it differs from other common loops, exploring its optional second parameter, using mapping in the return
statement, and tracking with keys. By the end, I hope you’ll have a clearer understanding of how the map()
function can be useful in your React projects.
Please note, this post is geared toward React beginners and new coders. Veteran users may not glean as much from the content.
Differences Between Loops
The map()
function is similar to a for-each
loop in that it will iterate through each item in an array. The strength of the map()
function is that it is more versatile in how and where you can apply it.
For example, the map()
function can be chainable. This means that extra functions such as the sort
or toString
methods can be directly tagged onto the end of the map()
.
Here’s a tangible example.
const names = ["phil", "todd", "jeff", "andy", "carl"]; const upperCase = names .map((n) => n.charAt(0).toUpperCase() + n.slice(1)) .sort();
Above, the sort function is chained directly to the map()
function, so the array is immediately sorted after the map()
function is finished. When the final upperCase
array is displayed, you can see that the names in the original array have been capitalized and sorted.
The same process, however, does not work with a normal for-each
loop. With a for-each
, the loop is not yet finished when the chained sort process begins. This results in an error since the sort function thinks the array is undefined.
This can be seen in the code below.
const names = ["phil", "todd", "jeff", "andy", "carl"]; const upperCase = names .map(({ name }) => name.charAt(0).toUpperCase() + name.slice(1)) .sort();
map()
Function’s Optional Second Parameter
Another important and useful tool of React’s map()
function is the optional second parameter.
The first parameter is the function you wish to apply to the array. In the example above, we put the entire function within the map()
function as the first parameter. The second parameter is reserved for an optional variable to be used in the first parameter’s function. This is accessible using the keyword this
.
const names = ["phil", "todd", "jeff", "andy", "carl"]; function nameFunction(val, index, arr) { return val.name.charAt(0).toUpperCase() + val.name.slice(1) + this.exclamation; } const upperCase = names.map(nameFunction, { exclamation: "!" }).sort();
In the example above, we have expanded our function to append the this.exclamation
variable to the end of each name. This is only accessible because the exclamation variable was used as the second parameter, which allowed it to override the this
keyword.
Here’s what happens when you run the code.
Using Mapping in the return
Statement
While the map()
function can be used globally as we’ve seen so far, it’s also a valuable tool for manipulating the return
statement. By plugging the map()
function directly into the jsx, you can manipulate the data with a specific design in mind.
For instance, all of the above examples were displayed on the page using this manner:
function App() { return ( <div className="App"> <header className="App-header"> <div> {upperCase.map((data) => ( <div>{data}</div> ))} </div> </header> </div> ); } export default App;
As you can see, this very basic app is using the map()
function within the return
to display each element of the upperCase
array we created earlier on its own line.
While this is simply using div
elements to display the data, you can use any element within the loops. For example, if I swap the div
elements for heading
elements, we can see that each element will be treated as a separate heading element in the same way a list would behave.
function App() { return ( <div className="App"> <header className="App-header"> <div> {upperCase.map((data) => ( <h1>{data}</h1> ))} </div> </header> </div> ); } export default App;
Tracking with Keys
Arguably the most important part of working with React’s map()
function is the association with keys. What this means is that the function maps based on the designated key.
In the examples we’ve used so far, we have only used a single array. If we were to expand the array to add an ID variable, we could then set up our mapping to map based on the key in this newly created key-value pair.
const names = [ { id: 1, name: "phil" }, { id: 2, name: "todd" }, { id: 3, name: "jeff" }, { id: 4, name: "andy" }, { id: 5, name: "carl" }, ];
In this scenario, if we told our array to sort by name as we did in the previous examples, then the new array would have the IDs associated with the names shift with them. If we then tied the mapping in the render to ID fields, any future changes made to the name field would automatically change what is rendered.
For example, if we were to delete Jeff from the list of names, the map()
function in the render would automatically register that Jeff has been deleted and remove any data under the id: 3
from the page.
Summary
React’s map()
function is a powerful tool that focuses on simplicity while also achieving versatility. Essentially, it replaces almost all instances where you would use a more traditional looping statement by providing more depth in potential manipulation of the data.
The map()
function allows a user to use it both globally and within a render. The optional extra parameter allows for even more flexibility by allowing the user to import an extra variable into the function being mapped. When manipulating data mapped within the render, the tracking of the data’s keys within the mapping function will ensure that changed data is properly updated and re-rendered when necessary.
I hope this post has shown you how useful the map()
function in React is. Feel free to drop a comment below to tell me how you use it and don’t forget the subscribe to the Keyhole Dev Blog for more.