javascript / intermediate
Snippet
Grouping Tabular Data by Category Using Array Reduce Inside Custom Hooks
Array.prototype.reduce allows transforming a flat list of objects into an indexed lookup dictionary grouped by dynamic keys. Encapsulating this pure data transformation inside a custom hook with useMemo prevents unnecessary recalculations during re-renders.
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
31
32
33
import { useMemo } from 'react';function useGroupedInventory(items) {return useMemo(() => {return items.reduce((accumulator, currentItem) => {const category = currentItem.category ?? 'Unassigned';if (!accumulator[category]) {accumulator[category] = [];}accumulator[category].push(currentItem);return accumulator;}, {});}, [items]);}export function InventoryList({ items }) {const grouped = useGroupedInventory(items);return (<div>{Object.entries(grouped).map(([category, list]) => (<section key={category}><h3>{category} ({list.length})</h3><ul>{list.map(item => <li key={item.id}>{item.name}</li>)}</ul></section>))}</div>);}
react
Breakdown
1
return items.reduce((accumulator, currentItem) => {
Iterates through the source array, accumulating aggregated category buckets into an object.
2
const category = currentItem.category ?? 'Unassigned';
Uses nullish coalescing to provide a safe fallback bucket when a category key is undefined or null.
3
accumulator[category].push(currentItem);
Appends the current item reference into the appropriate category array within the accumulator.
4
Object.entries(grouped).map(([category, list]) => (
Transforms the grouped object into key-value pairs for declarative JSX rendering.