0 day streak
javascript / intermediate
Snippet

Relational State Indexing with JavaScript Maps in React

When managing normalized or keyed data in React state, primitive JavaScript `Map` objects provide O(1) lookups and maintain insertion order. Because React state requires immutability, updating a Map involves cloning it into a new instance using `new Map(prevMap)` before setting updated values.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { useState } from 'react';
export function UserDirectory({ initialUsers }) {
const [usersById, setUsersById] = useState(() =>
new Map(initialUsers.map(user => [user.id, user]))
);
const updateRole = (userId, newRole) => {
setUsersById(prevMap => {
const user = prevMap.get(userId);
if (!user || user.role === newRole) return prevMap;
const nextMap = new Map(prevMap);
nextMap.set(userId, { ...user, role: newRole });
return nextMap;
});
};
const userList = Array.from(usersById.values());
return (
<ul>
{userList.map(user => (
<li key={user.id}>
{user.name} ({user.role})
<button onClick={() => updateRole(user.id, 'admin')}>Promote</button>
</li>
))}
</ul>
);
}
react
Breakdown
1
new Map(initialUsers.map(user => [user.id, user]))
Constructs a keyed Map from an array of entity objects using their unique identifiers as keys.
2
const nextMap = new Map(prevMap);
Creates a shallow clone of the Map instance to preserve state immutability in React.
3
const userList = Array.from(usersById.values());
Converts the Map values iterator back into a standard array to allow `.map()` rendering in JSX.