
Learn How to Use Map in React In and Out
When working with React apps, you will often find yourself using arrays in all sorts of situations, whether it be for working with state or rendering a list of items. When rendering a list of items, the map array method is used.
In this tutorial, you will learn how to use the map array method in React to loop over elements and create repeating code. We will also take a look at performance considerations and some common mistakes that you should avoid when working with map. But first, why do we need to use map in the first place?
Why Do We Need to Use Map?
The map array method in JavaScript is used for transforming an array using a callback function. The map loops through the array, and each item is transformed into whatever is returned from the array. For example, the following code doubles the values inside the array:
// This will return `[2, 4, 6, 8, 10]`
[1, 2, 3, 4, 5].map(i => i * 2) Why do we need to usemapin React? What is the problem with a regularforloop or aforEachloop?
The reason we cannot use a regular for loop in JSX is that a for loop is a statement, but JSX always expects an expression to be returned. As we cannot break or return from a forEach in JavaScript, a map is used as a declarative way to loop over arrays in React.
How to Use Map in React
Now that we have this out of the way, let's see how to actually use map in React. Most commonly, map is used for displaying a list of elements in a component.
For the most part, this data often comes from an API. Imagine that we have a dynamic menu for which we receive the data in the following format:
{
"menu": [
{
"name": "Home",
"link": "/"
},
{
"name": "About us",
"link": "/about"
},
{
"name": "Contact",
"link": "/contact"
}
]
} We can use a JSX expression to map through the array and display the elements using a map in the following way:
import React from 'react'
const App = () => {
const menu = [
{ name: 'Home', link: '/' },
{ name: 'About Us', link: '/about' }
]
return (
<ul>
{menu.map((item, index) => (
<li key={index}>
<a href={item.link}>{item.name}</a>
</li>
))}
</ul>
)
}
export default App Here, we used the Array.map method inside a JSX expression to display each element with its name and link. We can return the required elements from the function. This is equivalent to the following, where we explicitly write out the return keyword:
<ul>
{menu.map((item, index) => {
return (
<li key={index}>
<a href={item.link}>{item.name}</a>
</li>
)
})}
</ul> Note that when using return statements inside loops, we need to wrap them inside curly braces. When no curly braces are present, the return is implied in an arrow function.
// Return is implicit
menu.map(item => <li>{item}</li>)
// Return is explicit
menu.map(item => {
return <li>{item}</li>
}) Generally speaking, an implicit return is used most of the time. Using return explicitly can come in handy when we need to generate some type of data at each iteration in the loop and some minor extra logic is required. For example:
<ul>
{menu.map((item, index) => {
const label = `#${index + 1} `;
return (
<li key={index}>
<a href={item.link}>{label + item.name}</a>
</li>
)
})}
</ul> Using the key prop
You may have noticed that we are using a unique key prop on each li in the above examples. The key prop in React is used to identify each item in an array of items that are being rendered as a list. It helps React optimize the rendering process by allowing it to keep track of each item in the list.
The key prop must be unique among siblings, and it should remain the same for the lifetime of the component. Commonly, a unique identifier such as an ID or index is used as the value. Therefore, avoid using Math.random as the key for a component, as it doesn't provide unique values and duplicate keys can occur.
// β Don't use Math.random for a key
{posts.map(post => <Post details={post} key={Math.random()} />)}Omitting the key prop will result in the following warning: "Warning: Each child in a list should have a unique key prop."
Outsourcing loops
Last, but not least, it's worth mentioning that we can also extract loops before the render. This can be done by defining a function before the return keyword in the component:
import React from 'react'
const App = () => {
const menu = [
{ name: 'Home', link: '/' },
{ name: 'About Us', link: '/about' }
]
const MenuItems = () => menu.map((item, index) => (
<li key={index}>
<a href={item.link}>{item.name}</a>
</li>
))
return (
<ul>
<MenuItems />
</ul>
)
}
export default App A function that returns JSX always needs to be capitalized. Otherwise, it will be treated as a regular function.

Performance Considerations
Working with map in React is the recommended way to create loops. However, when not used optimally, it can cause performance issues. To help you avoid them, here are the three most common issues to look out for:
- Rendering long lists: One of the most common issues you can run into when using the
mapfunction in React is performance issues when rendering a large number of items. This can cause performance issues due to the time it takes to generate and update the virtual DOM. In this case, you may want to consider using pagination or infinite scrolling to improve performance:
const posts = [
{ link: '/map-in-react', title: 'How to work with maps in React' },
[0 ... 999]
]
// β Don't
{posts.map((post, index) => (
<li key={index}>
<a href={post.link}>{post.title}</a>
</li>
))}
// βοΈ Do use infinite scroll
<InfiniteScroll posts={posts} />
// βοΈ Do use pagination
const start = 0
const limit = 50
const page = posts.slice(start, limit)
{page.map((post, index) => (
<li key={index}>
<a href={post.link}>{post.title}</a>
</li>
))} - Frequent updates: Frequent updates are another common cause of poorly performing
mapfunctions in React. Usually, this can be solved alone by addressing the first point and avoiding loading a large list. If you still experience problems, it will most likely be because you are re-rendering the entire list, even if only a few items change. In this case, memoize components usingReact.memo:
// β Don't
const Post = ({ details }) => { ... }
// βοΈ Do memoize components
const Post = React.memo(({ details }) => { ... })
{posts.map(post => <Post details={post} />)} - Performing expensive calculations: Avoid performing expensive computations during rendering on large lists, such as reordering the entire array or updating the state of each element. In this case, you want to perform these calculations before the rendering process. Another option is to batch similar calls and execute them once on a user action or to memoize callbacks:
// β Avoid
{gallery.map((image, index) => (
<li key={index}>
<img
src={image.src}
alt={image.alt}
onClick={calculationHeavyFn}
/>
</li>
))}
// βοΈ Do batch similar calls
<React.Fragment>
{gallery.map((image, index) => (
<li key={index}>
<img ... />
</li>
))}
<button onClick={calculationHeavyFn}>Call once</button>
</React.Fragment>
// βοΈ Do memoize callbacks
const memoizedFn = useCallback(() => calculationHeavyFn(value), [value]);
{gallery.map((image, index) => (
<li key={index}>
<img onClick={memoizedFn} />
</li>
))} Common Mistakes
You also need to be aware of the most common mistakes people make when using map in React. The three most common mistakes are:
- Not using the
keyprop: One of the most common mistakes new React developers make is omitting thekeyprop. Thekeyprop is required, and forgetting it can lead to unexpected behavior.
// β Don't forget the key prop
{posts.map(post => <Post details={post} />)}
// β Don't use Math.random for a key
{posts.map(post => <Post details={post} key={Math.random()} />)}
// βοΈ Do use a unique key
{posts.map((post, index) => <Post details={post} key={index} />)}
// β
Prefer a unique ID
{posts.map(post => <Post details={post} key={post.id} />)} - Mutating the original array: Another common mistake people make when working with
mapin React is trying to mutate the original array when they want to update the state. In React, state is considered read-only. Always use the updater function to update the state:
// β Don't mutate the original array. This won't work.
<React.Fragment>
<ul>
{state.map(item => <li key={item}>{item}</li>)}
</ul>
<button onClick={() => state.push(state.length + 1)}>
Add new item
</button>
</React.Fragment>
// βοΈ Always use the updater function
<button onClick={() => setState([...state, state.length])}>Add new item</button> - Not checking for
null: When working with remote data, it is inevitable to run into cases where data will be missing. Not checking fornullorundefinedcan cause your application to crash when you receive data you don't expect. This can be resolved by using a logical AND or optional chaining:
// β Don't forget to check for optionality
{posts.map(post => <Post details={post} id={post.id} />)}
// βοΈ Do check for the presence of the data
{!!posts.length && posts.map(post => <Post details={post} key={post.id} />)}
// β
Prefer using optional chaining
{posts?.map(post => <Post details={post} id={post.id} />)} Use double negation with length to prevent rendering the length of the array.
Conclusion
By avoiding these mistakes, you can ensure that your React apps will be reliable and performant. Working with map in React is straightforward once you are familiar with the rules and core concepts. In summary, here are the key takeaways when working with map inside React:
- Always use
map - Always use the
keyprop - Always check for falsy values
- Consider lazy loading when working with long lists
If you would like to learn more about React, check out our guided roadmap where you can learn more about where to start and which concepts you need to master to become proficient in React. Congratulations on reaching the end! Happy coding! π¨βπ»

Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies:






