Map & Filter in React
map() and filter() are two of the most important JavaScript array methods used extensively in React.
They are especially useful when working with lists of data, such as:
- Displaying users
- Rendering products
- Showing menu items
- Creating table rows
- Filtering search results
- Displaying active/inactive records
- Rendering cards
- Filtering categories
- Combining filtering and rendering
- Transforming API response data before rendering
A very important point is:
map()is primarily used to transform data into another form, whilefilter()is primarily used to select/remove items based on a condition.
In React, both are commonly used inside JSX.
1. What is map()?
map() is a JavaScript array method that creates a new array by applying a function to every element of an existing array.
The basic idea is:
Original Array
|
| map()
↓
New Array
For example:
const numbers = [10, 20, 30];
const result = numbers.map(number => number * 2);
console.log(result);
Result:
[20, 40, 60]
The original array remains unchanged:
numbers = [10, 20, 30]
result = [20, 40, 60]
So map() is a non-mutating operation.
2. Why is map() important in React?
React applications frequently receive data as arrays.
For example:
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "David" },
{ id: 3, name: "Sarah" }
];
You may want to display every user.
Instead of manually writing:
<div>John</div>
<div>David</div>
<div>Sarah</div>
you can use:
{users.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
React evaluates the map() expression and produces React elements for every user.
Conceptually:
users
|
| map()
|
+---- user 1 → <div>John</div>
|
+---- user 2 → <div>David</div>
|
+---- user 3 → <div>Sarah</div>
React then renders those elements.
3. Basic map() syntax
array.map(item => {
return something;
});
Or using an arrow expression:
array.map(item => something)
In React, the second form is very common:
{users.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
4. map() with numbers
You can render an array of primitive values.
const numbers = [10, 20, 30, 40];
function App() {
return (
<div>
{numbers.map(number => (
<p key={number}>{number}</p>
))}
</div>
);
}
The result is conceptually:
<p>10</p>
<p>20</p>
<p>30</p>
<p>40</p>
5. map() with strings
const names = ["John", "David", "Sarah"];
function App() {
return (
<ul>
{names.map(name => (
<li key={name}>{name}</li>
))}
</ul>
);
}
Result:
John
David
Sarah
6. map() with objects
This is one of the most common React scenarios.
const users = [
{ id: 101, name: "John", age: 25 },
{ id: 102, name: "David", age: 30 },
{ id: 103, name: "Sarah", age: 28 }
];
You can render the properties:
{users.map(user => (
<div key={user.id}>
<h3>{user.name}</h3>
<p>Age: {user.age}</p>
</div>
))}
The important concept is that map() gives you the current array item.
For each execution:
user → { id: 101, name: "John", age: 25 }
user → { id: 102, name: "David", age: 30 }
user → { id: 103, name: "Sarah", age: 28 }
7. map() with index
The callback receives a second parameter called index.
const names = ["John", "David", "Sarah"];
{names.map((name, index) => (
<div key={name}>
{index + 1}. {name}
</div>
))}
Result:
1. John
2. David
3. Sarah
The callback can conceptually receive:
array.map((item, index) => ...)
For example:
users.map((user, index) => ...)
Here:
item → current object
index → current position
8. Should you use index as the React key?
You technically can:
{users.map((user, index) => (
<div key={index}>
{user.name}
</div>
))}
But if your objects have stable unique IDs, prefer:
{users.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
The preferred approach is a stable unique identifier:
key={user.id}
rather than:
key={index}
Indexes can cause reconciliation problems when items are inserted, removed, or reordered.
9. map() does not modify the original array
Consider:
const numbers = [1, 2, 3];
const doubled = numbers.map(number => number * 2);
You now have:
numbers
↓
[1, 2, 3]
doubled
↓
[2, 4, 6]
The original array is still:
[1, 2, 3]
This is important in React because immutable data handling is a major part of React state management.
10. map() can transform objects
map() does not have to return JSX.
It can transform one object structure into another.
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "David" }
];
const names = users.map(user => user.name);
Result:
["John", "David"]
Another example:
const usersWithDisplayName = users.map(user => ({
...user,
displayName: `User: ${user.name}`
}));
Now the new array contains:
{
id: 1,
name: "John",
displayName: "User: John"
}
So map() is not specifically a React method.
It is a JavaScript array method that React uses heavily.
More map() Examples for Transforming Objects in React
The pattern you showed is one of the most useful real-world uses of map():
const usersWithDisplayName = users.map(user => ({
...user,
displayName: `User: ${user.name}`
}));
Here, map() does not render JSX. Instead, it creates a new array of objects by adding, changing, calculating, or transforming properties.
The important pattern is:
const newArray = oldArray.map(item => ({
...item,
newProperty: calculatedValue
}));
The ...item preserves the existing properties, while the additional properties are added to the new object.
1. Add a Display Name
const users = [
{ id: 1, name: "John", age: 25 },
{ id: 2, name: "David", age: 30 },
{ id: 3, name: "Sarah", age: 28 }
];
const usersWithDisplayName = users.map(user => ({
...user,
displayName: `User: ${user.name}`
}));
Result:
[
{
id: 1,
name: "John",
age: 25,
displayName: "User: John"
},
{
id: 2,
name: "David",
age: 30,
displayName: "User: David"
},
{
id: 3,
name: "Sarah",
age: 28,
displayName: "User: Sarah"
}
]
The original properties are preserved, and displayName is added.
2. Add a Full Name
Suppose the API gives first and last names separately.
const users = [
{ id: 1, firstName: "John", lastName: "Smith" },
{ id: 2, firstName: "David", lastName: "Brown" },
{ id: 3, firstName: "Sarah", lastName: "Wilson" }
];
const usersWithFullName = users.map(user => ({
...user,
fullName: `${user.firstName} ${user.lastName}`
}));
Result:
[
{
id: 1,
firstName: "John",
lastName: "Smith",
fullName: "John Smith"
},
{
id: 2,
firstName: "David",
lastName: "Brown",
fullName: "David Brown"
}
]
This is useful when the backend provides separate fields but the UI needs a combined value.
3. Calculate Total Price
Suppose products contain price and quantity:
const products = [
{ id: 1, name: "Laptop", price: 50000, quantity: 2 },
{ id: 2, name: "Mouse", price: 1000, quantity: 3 },
{ id: 3, name: "Keyboard", price: 2000, quantity: 2 }
];
You can calculate the total for each product:
const productsWithTotal = products.map(product => ({
...product,
total: product.price * product.quantity
}));
Result:
[
{
id: 1,
name: "Laptop",
price: 50000,
quantity: 2,
total: 100000
},
{
id: 2,
name: "Mouse",
price: 1000,
quantity: 3,
total: 3000
}
]
This is a very common transformation when preparing API data for display.
4. Calculate Discounted Price
const products = [
{ id: 1, name: "Laptop", price: 50000 },
{ id: 2, name: "Mouse", price: 1000 },
{ id: 3, name: "Monitor", price: 15000 }
];
const productsWithDiscount = products.map(product => ({
...product,
discountedPrice: product.price * 0.9
}));
This adds a 10% discounted price.
For example:
Laptop
Original Price: 50000
Discounted Price: 45000
The original price is still preserved.
5. Add Discount Percentage
You can add both the discount percentage and calculated price:
const productsWithDiscount = products.map(product => {
const discount = 10;
const discountedPrice =
product.price - (product.price * discount / 100);
return {
...product,
discount,
discountedPrice
};
});
The resulting object contains:
{
id: 1,
name: "Laptop",
price: 50000,
discount: 10,
discountedPrice: 45000
}
This form is useful when the calculation requires multiple statements.
6. Convert Name to Uppercase
const users = [
{ id: 1, name: "john" },
{ id: 2, name: "david" },
{ id: 3, name: "sarah" }
];
const formattedUsers = users.map(user => ({
...user,
name: user.name.toUpperCase()
}));
Result:
[
{ id: 1, name: "JOHN" },
{ id: 2, name: "DAVID" },
{ id: 3, name: "SARAH" }
]
Here you're replacing an existing property rather than adding a new one.
Because the later name property appears after:
...user
it overrides the original name.
7. Convert Name to Lowercase
const formattedUsers = users.map(user => ({
...user,
name: user.name.toLowerCase()
}));
This is useful for normalizing data.
8. Add a Status Text
Suppose the API provides:
const users = [
{ id: 1, name: "John", active: true },
{ id: 2, name: "David", active: false },
{ id: 3, name: "Sarah", active: true }
];
You can create a display-friendly status:
const usersWithStatus = users.map(user => ({
...user,
statusText: user.active ? "Active" : "Inactive"
}));
Result:
{
id: 1,
name: "John",
active: true,
statusText: "Active"
}
and:
{
id: 2,
name: "David",
active: false,
statusText: "Inactive"
}
9. Add CSS Class Based on Status
This is particularly useful in React UI.
const usersWithCssClass = users.map(user => ({
...user,
cssClass: user.active
? "user-active"
: "user-inactive"
}));
Now your JSX can use:
{usersWithCssClass.map(user => (
<div key={user.id} className={user.cssClass}>
{user.name}
</div>
))}
The transformation separates data preparation from UI rendering.
10. Add a Boolean Property
Suppose you have:
const users = [
{ id: 1, name: "John", age: 25 },
{ id: 2, name: "David", age: 16 },
{ id: 3, name: "Sarah", age: 30 }
];
You can calculate whether each user is an adult:
const usersWithAdultStatus = users.map(user => ({
...user,
isAdult: user.age >= 18
}));
Result:
[
{
id: 1,
name: "John",
age: 25,
isAdult: true
},
{
id: 2,
name: "David",
age: 16,
isAdult: false
}
]
This is useful when the UI needs to make decisions based on calculated information.
11. Add Age Category
Instead of a Boolean, you can calculate a category:
const usersWithAgeCategory = users.map(user => ({
...user,
ageCategory:
user.age < 18
? "Minor"
: user.age < 60
? "Adult"
: "Senior"
}));
Result:
25 → Adult
16 → Minor
65 → Senior
The original object remains available along with the calculated category.
12. Add an Image URL
Suppose your API returns only an image filename:
const users = [
{ id: 1, name: "John", image: "john.jpg" },
{ id: 2, name: "David", image: "david.jpg" }
];
You can construct the complete URL:
const usersWithImageUrl = users.map(user => ({
...user,
imageUrl: `https://example.com/images/${user.image}`
}));
Now React can directly use:
{usersWithImageUrl.map(user => (
<img
key={user.id}
src={user.imageUrl}
alt={user.name}
/>
))}
13. Add a Formatted Date
Suppose:
const users = [
{
id: 1,
name: "John",
createdAt: "2026-11-01"
},
{
id: 2,
name: "David",
createdAt: "2026-11-05"
}
];
You can create a formatted date:
const formattedUsers = users.map(user => ({
...user,
displayDate: new Date(user.createdAt)
.toLocaleDateString("en-IN")
}));
Now the object can contain:
{
id: 1,
name: "John",
createdAt: "2026-11-01",
displayDate: "1/11/2026"
}
The original API value is preserved.
14. Add a Formatted Currency Value
Suppose:
const products = [
{ id: 1, name: "Laptop", price: 50000 },
{ id: 2, name: "Mouse", price: 1000 }
];
You can prepare a formatted display value:
const productsWithFormattedPrice = products.map(product => ({
...product,
displayPrice: product.price.toLocaleString("en-IN", {
style: "currency",
currency: "INR"
})
}));
Now you might have:
Laptop → ₹50,000.00
Mouse → ₹1,000.00
This is particularly useful when separating raw data from presentation-friendly data.
15. Add a Slug
Suppose you have article titles:
const articles = [
{ id: 1, title: "Introduction to React" },
{ id: 2, title: "Understanding React Props" }
];
You can create a URL-friendly slug:
const articlesWithSlug = articles.map(article => ({
...article,
slug: article.title
.toLowerCase()
.replaceAll(" ", "-")
}));
Result:
[
{
id: 1,
title: "Introduction to React",
slug: "introduction-to-react"
},
{
id: 2,
title: "Understanding React Props",
slug: "understanding-react-props"
}
]
16. Add a Detail URL
Using the slug:
const articlesWithUrl = articles.map(article => ({
...article,
url: `/articles/${article.id}`
}));
Result:
{
id: 1,
title: "Introduction to React",
url: "/articles/1"
}
This can then be used with React Router.
17. Add an Index Number
Sometimes you need a sequential display number.
const usersWithIndex = users.map((user, index) => ({
...user,
displayNumber: index + 1
}));
Result:
John → 1
David → 2
Sarah → 3
This is useful for tables.
{usersWithIndex.map(user => (
<tr key={user.id}>
<td>{user.displayNumber}</td>
<td>{user.name}</td>
</tr>
))}
18. Add a Position
You can create labels based on index:
const usersWithPosition = users.map((user, index) => ({
...user,
position: `Position ${index + 1}`
}));
Result:
John → Position 1
David → Position 2
Sarah → Position 3
19. Create a Nested Object
You can add an entire object as a property.
const usersWithContact = users.map(user => ({
...user,
contact: {
email: `${user.name.toLowerCase()}@example.com`,
phone: "1234567890"
}
}));
Now:
{
id: 1,
name: "John",
contact: {
email: "john@example.com",
phone: "1234567890"
}
}
This is useful when preparing data for a component that expects a nested structure.
20. Rename a Property
Suppose the API returns:
const users = [
{ id: 1, user_name: "John" },
{ id: 2, user_name: "David" }
];
Your React application prefers userName.
You can transform it:
const formattedUsers = users.map(user => ({
id: user.id,
userName: user.user_name
}));
Result:
[
{
id: 1,
userName: "John"
},
{
id: 2,
userName: "David"
}
]
Notice that we didn't use:
...user
because we specifically want to create a different object shape.
21. Rename While Preserving Other Properties
You can also selectively remove the old property.
const formattedUsers = users.map(({ user_name, ...user }) => ({
...user,
userName: user_name
}));
Suppose the original is:
{
id: 1,
user_name: "John",
age: 25
}
The result becomes:
{
id: 1,
age: 25,
userName: "John"
}
This is a useful destructuring pattern.
22. Convert API Data into Component Props
Suppose the API gives:
const users = [
{
id: 1,
first_name: "John",
last_name: "Smith",
email_address: "john@example.com"
}
];
But your component expects:
type UserCardProps = {
id: number;
name: string;
email: string;
};
You can transform the API data:
const userCards = users.map(user => ({
id: user.id,
name: `${user.first_name} ${user.last_name}`,
email: user.email_address
}));
Then:
{userCards.map(user => (
<UserCard
key={user.id}
name={user.name}
email={user.email}
/>
))}
This is a very useful architecture pattern:
API Response
↓
map()
↓
UI-friendly data
↓
React Component
23. Add a Display Label
Suppose categories are:
const categories = [
{ id: 1, code: "react" },
{ id: 2, code: "angular" },
{ id: 3, code: "dotnet" }
];
You can create display labels:
const categoriesWithLabel = categories.map(category => ({
...category,
label: category.code.toUpperCase()
}));
Result:
[
{
id: 1,
code: "react",
label: "REACT"
},
{
id: 2,
code: "angular",
label: "ANGULAR"
}
]
24. Add a Select-Friendly Value
For a dropdown:
const categoriesForSelect = categories.map(category => ({
value: category.id,
label: category.name
}));
Then:
<select>
{categoriesForSelect.map(category => (
<option
key={category.value}
value={category.value}
>
{category.label}
</option>
))}
</select>
This is a common transformation between backend data and UI component data.
25. Add a Full Display Label
Suppose:
const products = [
{ id: 1, name: "Laptop", price: 50000 },
{ id: 2, name: "Mouse", price: 1000 }
];
Create:
const productsWithLabel = products.map(product => ({
...product,
label: `${product.name} - ₹${product.price}`
}));
Result:
Laptop - ₹50000
Mouse - ₹1000
26. Calculate Percentage
Suppose students have marks:
const students = [
{ id: 1, name: "John", marks: 450 },
{ id: 2, name: "David", marks: 380 },
{ id: 3, name: "Sarah", marks: 490 }
];
Maximum mark is 500.
const studentsWithPercentage = students.map(student => ({
...student,
percentage: (student.marks / 500) * 100
}));
Result:
John → 90%
David → 76%
Sarah → 98%
27. Add Pass/Fail Status
const studentsWithResult = students.map(student => ({
...student,
result: student.marks >= 250
? "Pass"
: "Fail"
}));
Now the UI can simply use:
{studentsWithResult.map(student => (
<div key={student.id}>
{student.name} - {student.result}
</div>
))}
28. Add Multiple Calculated Properties
You can calculate several properties at once.
const studentsWithResult = students.map(student => {
const percentage = (student.marks / 500) * 100;
return {
...student,
percentage,
result: percentage >= 50 ? "Pass" : "Fail",
grade:
percentage >= 90 ? "A+" :
percentage >= 80 ? "A" :
percentage >= 70 ? "B" :
percentage >= 50 ? "C" :
"F"
};
});
Now one transformation prepares the data for the UI.
29. Add Array Length Information
Suppose each department has employees:
const departments = [
{
id: 1,
name: "IT",
employees: ["John", "David", "Sarah"]
},
{
id: 2,
name: "HR",
employees: ["Mike", "Alex"]
}
];
You can add employee count:
const departmentsWithCount = departments.map(department => ({
...department,
employeeCount: department.employees.length
}));
Result:
IT → 3 employees
HR → 2 employees
30. Transform Nested Data
Suppose:
const departments = [
{
id: 1,
name: "IT",
employees: [
{ id: 101, name: "John" },
{ id: 102, name: "David" }
]
}
];
You can add display names to the nested employees:
const updatedDepartments = departments.map(department => ({
...department,
employees: department.employees.map(employee => ({
...employee,
displayName: `Employee: ${employee.name}`
}))
}));
The structure becomes:
Department
|
+-- Employee
| +-- name
| +-- displayName
|
+-- Employee
+-- name
+-- displayName
This demonstrates that map() can be nested when your data structure is nested.
filter() + map() Transformation
31. Filter First, Then Transform
You can combine selection and transformation:
const activeUsers = users
.filter(user => user.active)
.map(user => ({
...user,
displayName: `Active User: ${user.name}`
}));
This is different from simply rendering:
{users
.filter(user => user.active)
.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
In the first example, map() creates new data objects.
In the second example, map() creates React elements.
That distinction is important.
map() for Data vs map() for UI
32. Two major uses of map()
Data transformation
const transformedUsers = users.map(user => ({
...user,
displayName: `User: ${user.name}`
}));
The result is data:
Array of objects
UI rendering
{users.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
The result is:
Array of React elements
So map() has a broader purpose than simply rendering lists.
map()
|
+-- Transform data
|
+-- Create JSX
|
+-- Calculate properties
|
+-- Change object shape
|
+-- Prepare component props
|
+-- Convert API data for UI
A Very Important Pattern
33. Preserve + Override + Add
A powerful pattern is:
const result = users.map(user => ({
...user,
name: user.name.toUpperCase(),
displayName: `User: ${user.name}`,
isAdult: user.age >= 18
}));
Here three things happen:
...user
↓
Preserve existing properties
name: ...
↓
Override existing property
displayName: ...
isAdult: ...
↓
Add new properties
For example:
{
id: 1,
name: "JOHN",
age: 25,
displayName: "User: JOHN",
isAdult: true
}
The order of properties matters when overriding.
For example:
{
...user,
name: "New Name"
}
means "New Name" wins.
But:
{
name: "New Name",
...user
}
means the original user.name wins because the spread comes later.
34. Practical React Example
Suppose an API returns:
const users = [
{
id: 1,
firstName: "John",
lastName: "Smith",
age: 25,
active: true
},
{
id: 2,
firstName: "David",
lastName: "Brown",
age: 16,
active: false
}
];
Prepare the data:
const preparedUsers = users
.filter(user => user.active)
.map(user => ({
...user,
fullName: `${user.firstName} ${user.lastName}`,
displayName: `User: ${user.firstName} ${user.lastName}`,
isAdult: user.age >= 18,
statusText: "Active"
}));
Now the React rendering becomes very simple:
{preparedUsers.map(user => (
<div key={user.id}>
<h3>{user.fullName}</h3>
<p>{user.displayName}</p>
<p>{user.isAdult ? "Adult" : "Minor"}</p>
<p>{user.statusText}</p>
</div>
))}
The responsibility is nicely separated:
Raw API Data
↓
filter()
↓
Select required records
↓
map()
↓
Prepare UI-friendly objects
↓
map()
↓
Create React elements
↓
UI
This is a pattern you will frequently see in real React applications.
35. The Key Idea to Remember
When you see:
array.map(item => ({
...item,
something: calculatedValue
}));
read it as:
"Take every object from the original array, preserve its existing properties, and create a new object with additional or modified properties."
For example:
const usersWithDisplayName = users.map(user => ({
...user,
displayName: `User: ${user.name}`
}));
means:
Original User
↓
Copy existing properties
↓
Add displayName
↓
Create new User object
↓
Store in a new array
And when you combine it with filter():
const result = users
.filter(user => user.active)
.map(user => ({
...user,
displayName: `Active User: ${user.name}`
}));
the meaning becomes:
users
↓
filter()
↓
Only active users
↓
map()
↓
Add/modify properties
↓
New object array
This filter() → map() → transform objects pattern is one of the most useful patterns to master for React development.
Filter in React
11. What is filter()?
filter() creates a new array containing only the elements that satisfy a condition.
For example:
const numbers = [10, 20, 30, 40, 50];
const result = numbers.filter(number => number > 25);
Result:
[30, 40, 50]
Conceptually:
10 → false → removed
20 → false → removed
30 → true → included
40 → true → included
50 → true → included
So:
filter()decides which elements should remain in the array.
12. Basic filter() syntax
array.filter(item => condition)
Example:
const activeUsers = users.filter(user => user.active);
Only users for whom:
user.active
is truthy will remain.
13. Basic React filtering
Suppose:
const users = [
{ id: 1, name: "John", active: true },
{ id: 2, name: "David", active: false },
{ id: 3, name: "Sarah", active: true }
];
You can display only active users:
{users
.filter(user => user.active)
.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
The process is:
users
|
| filter()
↓
active users
|
| map()
↓
React elements
The result is:
John
Sarah
David is removed before map() runs.
14. filter() with numbers
const numbers = [10, 15, 20, 25, 30];
const evenNumbers = numbers.filter(number => number % 2 === 0);
Result:
[10, 20, 30]
You can render them:
{numbers
.filter(number => number % 2 === 0)
.map(number => (
<p key={number}>{number}</p>
))}
15. filter() with objects
const products = [
{ id: 1, name: "Laptop", price: 50000 },
{ id: 2, name: "Mouse", price: 1000 },
{ id: 3, name: "Keyboard", price: 2000 }
];
Suppose you only want products costing more than ₹2,000:
const expensiveProducts = products.filter(
product => product.price > 2000
);
Result:
Laptop
and the resulting array is:
[
{ id: 1, name: "Laptop", price: 50000 }
]
Combining filter() and map()
16. The most common React pattern
One of the most important patterns is:
array.filter(...).map(...)
For example:
const users = [
{ id: 1, name: "John", active: true },
{ id: 2, name: "David", active: false },
{ id: 3, name: "Sarah", active: true }
];
function App() {
return (
<div>
{users
.filter(user => user.active)
.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
</div>
);
}
The important functionality is:
Original users
↓
filter()
↓
Active users only
↓
map()
↓
React elements
↓
Render
This is generally the cleanest approach when you want to select data first and then render it.
17. filter() first, then map()
This:
users
.filter(user => user.active)
.map(user => (
<div key={user.id}>
{user.name}
</div>
))
means:
- Start with all users.
- Remove inactive users.
- Take the remaining users.
- Convert each remaining user into JSX.
- React renders the JSX.
For example:
John → active → keep
David → inactive → remove
Sarah → active → keep
Then:
John → JSX
Sarah → JSX
Conditional Rendering with map()
18. Using map() with a condition
You can also use a condition directly inside map().
{users.map(user => (
user.active ? (
<div key={user.id}>
{user.name}
</div>
) : null
))}
Here, map() processes every user.
For active users:
return JSX
For inactive users:
return null
React does not render null.
So this works, but when your goal is specifically to remove unwanted items, filter().map() is often clearer.
19. Difference between filter().map() and conditional map()
These two approaches can produce the same UI.
Approach 1
users
.filter(user => user.active)
.map(user => (
<div key={user.id}>
{user.name}
</div>
))
Approach 2
users.map(user =>
user.active ? (
<div key={user.id}>
{user.name}
</div>
) : null
)
The conceptual difference is:
filter().map()
First decide:
Which items should exist?
Then:
How should they be rendered?
Whereas:
map() + condition
Process every item,
then decide whether to return JSX or null.
If you are actually filtering a collection, filter().map() communicates the intent more clearly.
Map with Multiple JSX Elements
20. Returning multiple elements from map()
You can return a React Fragment:
{users.map(user => (
<React.Fragment key={user.id}>
<h3>{user.name}</h3>
<p>{user.email}</p>
</React.Fragment>
))}
This is useful when each array item needs to generate multiple sibling elements.
You can also use the shorthand fragment syntax:
{users.map(user => (
<>
<h3>{user.name}</h3>
<p>{user.email}</p>
</>
))}
However, there is an important issue.
The shorthand:
<>
cannot directly receive a key.
Therefore, when rendering a list, use:
<React.Fragment key={user.id}>
if the fragment itself represents the list item.
Map with Components
21. Using map() to render components
This is one of the most important real-world React patterns.
Suppose you have:
const products = [
{ id: 1, name: "Laptop", price: 50000 },
{ id: 2, name: "Mouse", price: 1000 },
{ id: 3, name: "Keyboard", price: 2000 }
];
You have a reusable component:
type ProductProps = {
name: string;
price: number;
};
const ProductCard = ({ name, price }: ProductProps) => {
return (
<div>
<h3>{name}</h3>
<p>₹{price}</p>
</div>
);
};
Now:
{products.map(product => (
<ProductCard
key={product.id}
name={product.name}
price={product.price}
/>
))}
The flow becomes:
products
↓
map()
↓
ProductCard
↓
ProductCard
↓
ProductCard
This allows one reusable component to render many records.
Filter with Search
22. Filtering data based on search text
A very common React application is a search box.
Suppose:
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "David" },
{ id: 3, name: "Jonathan" }
];
You can filter users:
const searchText = "jo";
const filteredUsers = users.filter(user =>
user.name.toLowerCase().includes(searchText.toLowerCase())
);
The result is:
John
Jonathan
Then render:
{filteredUsers.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
This pattern is extremely common:
User Input
↓
Search Text
↓
filter()
↓
Matching Data
↓
map()
↓
UI
Filter by Multiple Conditions
23. Using && inside filter()
You can have multiple conditions.
const filteredUsers = users.filter(
user => user.active && user.age >= 18
);
This means:
active must be true
AND
age must be >= 18
Only users satisfying both conditions remain.
24. Using || inside filter()
You can also use OR conditions.
const filteredUsers = users.filter(
user => user.role === "Admin" || user.role === "Manager"
);
This keeps:
Admin
OR
Manager
25. Combining search and status filtering
You can combine several conditions:
const filteredUsers = users.filter(user =>
user.active &&
user.name.toLowerCase().includes(searchText.toLowerCase())
);
This means:
User must be active
AND
Name must contain search text
Then:
{filteredUsers.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
Map and Filter with React State
26. map() and filter() with useState
Consider a todo application:
const [tasks, setTasks] = useState([
{ id: 1, title: "Learn React", completed: true },
{ id: 2, title: "Learn TypeScript", completed: false },
{ id: 3, title: "Learn Angular", completed: false }
]);
You can display the tasks:
{tasks.map(task => (
<div key={task.id}>
{task.title}
</div>
))}
The state array is not modified by map().
27. Removing an item using filter()
Suppose the user clicks Delete.
You can remove the task like this:
const deleteTask = (id: number) => {
setTasks(tasks.filter(task => task.id !== id));
};
Suppose:
tasks:
1 → Learn React
2 → Learn TypeScript
3 → Learn Angular
If:
id = 2
then:
tasks.filter(task => task.id !== 2)
produces:
1 → Learn React
3 → Learn Angular
This is a very important React pattern.
You are not modifying the existing state array.
Instead:
Old Array
↓
filter()
↓
New Array
↓
setTasks()
↓
React re-render
Map for Updating State Data
28. Updating an item using map()
Suppose you want to mark a task as completed.
const completeTask = (id: number) => {
setTasks(tasks.map(task =>
task.id === id
? { ...task, completed: true }
: task
));
};
Here map() creates a new array.
For the selected task:
{ ...task, completed: true }
creates a new object.
For other tasks:
task
is returned unchanged.
Conceptually:
Task 1 → unchanged
Task 2 → create updated object
Task 3 → unchanged
Result:
Old state
↓
map()
↓
New state
↓
setTasks()
This is a fundamental immutable-state pattern in React.
Map vs Filter
29. Important difference
map() |
filter() |
|---|---|
| Transforms items | Selects items |
| Usually keeps the same number of items | Can reduce the number of items |
| Returns a new array | Returns a new array |
| Callback usually returns transformed value | Callback returns true or false |
| Commonly used for rendering | Commonly used for selecting data |
| Can transform objects | Can remove objects based on conditions |
Example:
const numbers = [1, 2, 3, 4];
Using map():
numbers.map(x => x * 10);
Result:
[10, 20, 30, 40]
Same number of elements.
Using filter():
numbers.filter(x => x > 2);
Result:
[3, 4]
Fewer elements.
Map and Filter Together
30. Real-world example
Consider:
const products = [
{ id: 1, name: "Laptop", price: 50000, available: true },
{ id: 2, name: "Mouse", price: 1000, available: false },
{ id: 3, name: "Keyboard", price: 2000, available: true },
{ id: 4, name: "Monitor", price: 15000, available: true }
];
Suppose you want to display only available products costing more than ₹5,000.
{products
.filter(product =>
product.available && product.price > 5000
)
.map(product => (
<div key={product.id}>
<h3>{product.name}</h3>
<p>₹{product.price}</p>
</div>
))}
The processing is:
All Products
|
| filter()
|
↓
Available + price > 5000
|
| map()
|
↓
React Product Cards
Multiple filter() Calls
31. Chaining multiple filters
You can do:
const result = users
.filter(user => user.active)
.filter(user => user.age >= 18);
This is valid.
It means:
First filter
↓
active users
↓
Second filter
↓
adult active users
However, if the conditions are simple, you can usually combine them:
const result = users.filter(
user => user.active && user.age >= 18
);
Both approaches are valid.
Multiple map() Calls
32. Chaining multiple map() calls
You can also chain map():
const result = numbers
.map(number => number * 2)
.map(number => number + 10);
For:
[1, 2, 3]
first:
[2, 4, 6]
then:
[12, 14, 16]
But multiple map() calls should be used only when they make the transformation clearer.
Map with Filter in Reverse Order
33. map().filter() is also possible
You can technically do:
numbers
.map(number => number * 2)
.filter(number => number > 10)
For:
[1, 5, 8]
map() produces:
[2, 10, 16]
Then filter() produces:
[16]
The order matters.
Compare:
numbers
.filter(number => number > 5)
.map(number => number * 2)
with:
numbers
.map(number => number * 2)
.filter(number => number > 5)
They are not necessarily equivalent.
Filter Before Map vs Map Before Filter
34. Why order matters
Suppose:
const numbers = [2, 4, 6, 8];
Filter first
numbers
.filter(number => number > 4)
.map(number => number * 10);
Result:
[60, 80]
Map first
numbers
.map(number => number * 10)
.filter(number => number > 4);
Result:
[20, 40, 60, 80]
The second condition:
number > 4
is applied after the values have been transformed.
Therefore, always understand what data is entering the next operation.
Map, Filter and Reduce
35. map(), filter() and reduce() are different
These three array methods are frequently used together.
map()
Transform every item:
numbers.map(x => x * 2);
filter()
Select some items:
numbers.filter(x => x > 10);
reduce()
Combine items into one result:
numbers.reduce((total, x) => total + x, 0);
Conceptually:
map
↓
Transform
filter
↓
Select
reduce
↓
Combine
Map with Optional Data
36. Handling possibly undefined arrays
Sometimes API data may not be available immediately.
For example:
const [users, setUsers] = useState<User[]>();
This can cause a problem:
users.map(...)
because users could be undefined.
You can use optional chaining:
{users?.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
If users is undefined, the expression does not attempt to call map().
37. Providing a default array
Another approach:
{(users ?? []).map(user => (
<div key={user.id}>
{user.name}
</div>
))}
This means:
users exists
↓
use users
users is null/undefined
↓
use []
Then map() always operates on an array.
Filter with Optional Data
38. Optional chaining with filter
You can also use:
const activeUsers = users?.filter(user => user.active);
But remember that the result may be:
User[] | undefined
If you want an array regardless:
const activeUsers = (users ?? []).filter(
user => user.active
);
Then:
activeUsers.map(...)
is safe.
Map and Filter with API Data
39. Rendering API results
Suppose an API returns:
[
{
id: 1,
title: "React",
published: true
},
{
id: 2,
title: "Angular",
published: false
},
{
id: 3,
title: "TypeScript",
published: true
}
]
You can render published articles:
{articles
.filter(article => article.published)
.map(article => (
<article key={article.id}>
<h3>{article.title}</h3>
</article>
))}
This is a very common production pattern.
Map and Filter with Select Dropdowns
40. Rendering <option> elements
Suppose:
const countries = [
{ id: 1, name: "India", active: true },
{ id: 2, name: "USA", active: true },
{ id: 3, name: "Canada", active: false }
];
You can display active countries:
<select>
{countries
.filter(country => country.active)
.map(country => (
<option key={country.id} value={country.id}>
{country.name}
</option>
))}
</select>
This is another common use of filter().map().
Map and Filter with Tables
41. Rendering table rows
<table>
<tbody>
{users
.filter(user => user.active)
.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.email}</td>
</tr>
))}
</tbody>
</table>
Here:
filter()
controls which rows appear.
And:
map()
controls how each row is generated.
Map and Filter with Cards
42. Rendering cards
<div className="products">
{products
.filter(product => product.available)
.map(product => (
<div className="card" key={product.id}>
<h3>{product.name}</h3>
<p>₹{product.price}</p>
</div>
))}
</div>
This is one of the most common React patterns for product grids.
Filter with Boolean Properties
43. Short form filter
If the property itself is boolean:
const activeUsers = users.filter(user => user.active);
You don't need:
users.filter(user => user.active === true);
Both work, but:
user.active
is cleaner.
For inactive users:
const inactiveUsers = users.filter(user => !user.active);
Filter with String Comparison
44. Filtering by category
const products = [
{ id: 1, name: "Laptop", category: "Electronics" },
{ id: 2, name: "Chair", category: "Furniture" },
{ id: 3, name: "Phone", category: "Electronics" }
];
Filter electronics:
const electronics = products.filter(
product => product.category === "Electronics"
);
Then:
{electronics.map(product => (
<div key={product.id}>
{product.name}
</div>
))}
Filter with Case-Insensitive Search
45. Search filtering
A robust search pattern is:
const result = products.filter(product =>
product.name
.toLowerCase()
.includes(searchText.toLowerCase())
);
For example:
searchText = "lap"
will match:
Laptop
even if the user types:
LAP
Lap
lAp
because both values are converted to lowercase.
Nested map()
46. Mapping nested arrays
Suppose:
const departments = [
{
id: 1,
name: "IT",
employees: [
{ id: 101, name: "John" },
{ id: 102, name: "David" }
]
},
{
id: 2,
name: "HR",
employees: [
{ id: 103, name: "Sarah" }
]
}
];
You can use nested map():
{departments.map(department => (
<div key={department.id}>
<h2>{department.name}</h2>
{department.employees.map(employee => (
<p key={employee.id}>
{employee.name}
</p>
))}
</div>
))}
The structure is:
departments
|
| map()
↓
department
|
| employees
|
| map()
↓
employee
Nested map() is useful when the data itself has a hierarchical structure.
Nested Filter and Map
47. Filtering nested data
Suppose you only want departments with employees:
{departments
.filter(department => department.employees.length > 0)
.map(department => (
<div key={department.id}>
<h2>{department.name}</h2>
{department.employees.map(employee => (
<p key={employee.id}>
{employee.name}
</p>
))}
</div>
))}
You can also filter the nested employees:
{departments.map(department => (
<div key={department.id}>
<h2>{department.name}</h2>
{department.employees
.filter(employee => employee.active)
.map(employee => (
<p key={employee.id}>
{employee.name}
</p>
))}
</div>
))}
Important: map() Does Not Change Your React State
48. Does map() modify the original array?
No.
For example:
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "David" }
];
users.map(user => (
<div key={user.id}>{user.name}</div>
));
The users array remains unchanged.
Similarly:
const result = users.map(user => ({
...user,
name: user.name.toUpperCase()
}));
does not change the original users array.
You get a new array:
users
↓
Original objects
result
↓
New array containing transformed objects
This distinction is especially important when working with React state.
Important: filter() Does Not Change Your React State
49. Does filter() remove items from the original array?
No.
For:
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "David" }
];
const activeUsers = users.filter(user => user.id === 1);
the original array remains:
John
David
The new array contains:
John
So filter() does not physically delete an item from the original array.
It creates another array containing the selected elements.
map() Return Value
50. What happens if you don't return from map()?
Consider:
const result = numbers.map(number => {
number * 2;
});
This does not return the multiplied values.
Because the arrow function uses {}:
number => {
number * 2;
}
and there is no return.
You need:
const result = numbers.map(number => {
return number * 2;
});
Or:
const result = numbers.map(number => number * 2);
In React JSX, this distinction is very important.
Correct:
{users.map(user => (
<div key={user.id}>
{user.name}
</div>
))}
Incorrect:
{users.map(user => {
<div key={user.id}>
{user.name}
</div>
})}
The second version doesn't return the JSX.
filter() Return Value
51. What should filter() return?
The callback should produce a truthy/falsy result.
For example:
users.filter(user => user.active);
or:
users.filter(user => user.age >= 18);
Conceptually:
true → keep item
false → remove item
So:
users.filter(user => user.active)
means:
active = true → keep
active = false → remove
filter() Does Not Render JSX
52. A common mistake
Don't think of:
filter()
as a rendering method.
For example:
users.filter(user => (
<div>{user.name}</div>
))
is incorrect conceptually.
filter() is asking:
"Should I keep this item?"
It expects something equivalent to:
true / false
map() is the method used to transform the item into JSX:
users.map(user => (
<div>{user.name}</div>
))
Therefore:
filter()
→ Which items?
map()
→ What should each item become?
map() Can Return Strings, Numbers, JSX or Objects
53. What can map() produce?
map() can transform an array into another array of almost anything.
For example:
const numbers = [1, 2, 3];
numbers.map(x => x * 2);
produces:
[2, 4, 6]
Strings:
numbers.map(x => `Number ${x}`);
produces:
["Number 1", "Number 2", "Number 3"]
JSX:
numbers.map(x => <p key={x}>{x}</p>);
produces an array of React elements.
So:
map()itself does not mean "render". It means "transform every element into a new value."
React simply makes JSX one of the most useful things to return from map().
Performance Considerations
54. Should you worry about filter().map()?
Usually, no.
For normal UI collections:
users
.filter(user => user.active)
.map(user => (
<UserCard key={user.id} user={user} />
))
is perfectly normal React code.
For very large datasets, performance considerations become more important.
You may need:
- Pagination
- Server-side filtering
- Memoization
- Virtualized lists
- Efficient selectors
- Debounced search
But don't avoid filter().map() simply because it creates intermediate arrays.
filter() + map() vs forEach()
55. Why not use forEach() for React rendering?
You may see:
users.forEach(user => {
// ...
});
But forEach() does not return a new array.
React list rendering is naturally suited to:
users.map(user => (
<UserCard key={user.id} user={user} />
))
because map() produces an array of React elements.
Therefore:
forEach()
→ perform an action for each item
map()
→ transform every item into a new value
Complete Real-World Example
56. Product filtering and rendering
import { useState } from "react";
type Product = {
id: number;
name: string;
category: string;
price: number;
available: boolean;
};
const products: Product[] = [
{
id: 1,
name: "Laptop",
category: "Electronics",
price: 50000,
available: true
},
{
id: 2,
name: "Mouse",
category: "Electronics",
price: 1000,
available: false
},
{
id: 3,
name: "Chair",
category: "Furniture",
price: 7000,
available: true
},
{
id: 4,
name: "Keyboard",
category: "Electronics",
price: 2000,
available: true
}
];
export default function ProductList() {
const [searchText, setSearchText] = useState("");
const filteredProducts = products.filter(product =>
product.available &&
product.name
.toLowerCase()
.includes(searchText.toLowerCase())
);
return (
<div>
<input
type="text"
value={searchText}
onChange={e => setSearchText(e.target.value)}
placeholder="Search products"
/>
<div>
{filteredProducts.map(product => (
<div key={product.id}>
<h3>{product.name}</h3>
<p>{product.category}</p>
<p>₹{product.price}</p>
</div>
))}
</div>
</div>
);
}
The complete functionality is:
User types search text
↓
searchText
↓
filter()
↓
Available products
+
Matching search text
↓
map()
↓
Product JSX
↓
React UI
This is one of the most practical uses of filter() and map() together.
Important React Rule
57. Don't mutate the array while using map() or filter()
Avoid patterns like:
users.map(user => {
user.name = user.name.toUpperCase();
return user;
});
This mutates the existing objects.
Prefer creating a new object:
const updatedUsers = users.map(user => ({
...user,
name: user.name.toUpperCase()
}));
Similarly, don't use splice() to directly modify React state arrays.
Instead of:
tasks.splice(index, 1);
setTasks(tasks);
prefer:
setTasks(tasks.filter(task => task.id !== id));
This creates a new array and follows React's immutable update pattern.
The Most Important Patterns to Remember
58. Basic map()
{items.map(item => (
<div key={item.id}>
{item.name}
</div>
))}
Use when you want to render/transform every item.
59. Basic filter()
const activeItems = items.filter(item => item.active);
Use when you want only items satisfying a condition.
60. filter() + map()
{items
.filter(item => item.active)
.map(item => (
<div key={item.id}>
{item.name}
</div>
))}
Use when you want to select items first and then render them.
61. map() + condition
{items.map(item =>
item.active ? (
<div key={item.id}>
{item.name}
</div>
) : null
)}
Use when rendering logic itself determines whether an item produces JSX.
62. Filter + search + map
{items
.filter(item =>
item.name.toLowerCase().includes(searchText.toLowerCase())
)
.map(item => (
<div key={item.id}>
{item.name}
</div>
))}
Very common for search interfaces.
63. Filter + multiple conditions + map
{products
.filter(product =>
product.available &&
product.price > 5000 &&
product.category === "Electronics"
)
.map(product => (
<ProductCard
key={product.id}
product={product}
/>
))}
Very common for product/catalog applications.
64. Map for state updates
setTasks(tasks.map(task =>
task.id === id
? { ...task, completed: true }
: task
));
Use map() when you want to create a new state array while changing one or more items.
65. Filter for state deletion
setTasks(tasks.filter(task => task.id !== id));
Use filter() when you want to create a new state array without certain items.
66. The Core Concept
The easiest way to remember the difference is:
ARRAY
|
┌─────────┴─────────┐
| |
map() filter()
| |
Transform Select
| |
Every item Some items
| |
↓ ↓
New array New array
In React:
DATA
|
↓
filter()
|
Choose required
records
|
↓
map()
|
Convert records
into JSX
|
↓
React
|
↓
UI
The most important distinction is:
filter()answers "Which items should I keep?"
map()answers "What should each item become?"
Once this distinction is clear, most React list-rendering code becomes straightforward.