Feb 15, 2026
TypeScript
JavaScript
Avoid Calling Lookup Functions Inside map

Overview
When rendering UI lists in React, it is common to iterate over arrays using map.
In some cases, each item only contains an ID, and additional display information (such as icons or colors) must be retrieved from a local definition.
My initial implementation performed this lookup inside the rendering loop.
It worked, but it felt structurally uncomfortable.
I started wondering:
Is it necessary to look up the data during each iteration?
A Naive Approach
A straightforward implementation looks like this:
{techStacks.map((techStack) => {
const localStack = getTechStack(techStack.id);
if (!localStack) return null;
return (
<li key={localStack.id}>
...
<li>
);a
})}
The helper function looks like this:
export function getTechStack(id: string): TechStack | undefined {
return TECH_STACKS.find((stack) => stack.id === id);
}
This works correctly. However, it introduces several concerns.
The Problem
While not catastrophic, this pattern has structural drawbacks:
- The lookup function is called on every iteration.
- find performs a linear search each time.
- Rendering logic is mixed with data transformation.
The Refactor
Instead of searching for the data inside the map loop, I refactored the code so that the necessary data is prepared beforehand and then expanded in the UI.
import { TECH_STACKS } from '@/constants/techStacks';
import type { TechStack } from '@/constants/techStacks';
export function getTechStacksByIds(ids: string[]): TechStack[] {
const techStackMap = new Map(
TECH_STACKS.map((stack) => [stack.id, stack])
);
return ids
.map((id) => techStackMap.get(id))
.filter((stack): stack is TechStack => Boolean(stack));
}
First, I convert the locally defined data into a Map so that it can be accessed by ID more easily.
Then, I iterate over the array of IDs passed as an argument and retrieve the corresponding data from techStackMap.
Since Map.get() can return undefined, I use Boolean(stack) in combination with a type predicate to ensure that undefined values are removed from the array.
Now, the UI receives already-prepared data:
const stacks = getTechStacksByIds(techStacks.map((s) => s.id));
return (
<ul>
{stacks.map((stack) => (
<li key={stack.id}>
...
</li>
))}
</ul>
);
On the UI side, I only extract the IDs and pass them to getTechStacksByIds.
The function returns fully prepared data, which can then be mapped directly in the component.
This way, the data no longer needs to be searched during each iteration.
