A nested array is essentially an array of arrays, you can visualise them as a table, or a 2D grid. To map a nested array, you can use either a combination of the flat and map array functions, or a map within a map. Which one you might want to use depends on your situation, so I’ll explain each with an example. If your data is just a 1D array, you can simply just use a regular map, which you can check out with this tutorial.
Flat + Map
The flat function turns our 2-Dimensional array into a 1D array, which we can then simply map over to produce our components. In this example, I’ve created a simple shopping list, and grouped some items together by food group.
const shoppingCart = [
['apple', 'banana', 'cherry'],
['eggs', 'milk'],
['carrots', 'onions'],
];
And here’s the code for our component:
function ShoppingListItem({ item }) {
return <li className="bg-neutral-800 p-2 font-normal shadow">{item}</li>;
}
function ShoppingList() {
return (
<div className="flex h-screen w-screen items-center justify-center">
<div className="flex flex-col items-start justify-center rounded bg-neutral-800 p-8 text-3xl font-bold text-white shadow">
<h1 className="w-full border-b-8 pb-2">Shopping List</h1>
<ul>
{shoppingCart.flat().map((item) => (
<ShoppingListItem key={item} item={item} />
))}
</ul>
</div>
</div>
);
}
Here’s what our page looks like:
The related items are grouped together, but to display them we just want a list of our items. This approach is the simplest method, useful for when your data being grouped together doesn’t matter. The code is shorter at the cost of simplifying the structure of our data. Another example might be something like an Instagram feed, where you get the posts from separate users and put them all into one feed.
Using a Nested Map
In a lot of cases, you might want to keep the structure of your nested data. In this example, we’ll refactor our shopping list to keep our food groups together.
function ShoppingListItem({ item, white }) {
return (
<div
key={item}
className={ //Just to have striped rows
'rounded p-5 ' +
(white
? 'bg-neutral-700 text-white'
: 'bg-neutral-100 text-black')
}>
{item}
</div>
);
}
function ShoppingListRow({ items, white }) {
return (
<li className="flex gap-2">
{items.map((item) => (
<ShoppingListItem key={item} item={item} white={white} />
))}
</li>
);
}
function ShoppingListGrouped() {
return (
<div className="flex h-screen w-screen items-center justify-center">
<div className="flex flex-col items-start justify-center gap-8 rounded bg-neutral-800 p-8 text-3xl font-bold text-white shadow">
<h1 className="w-full border-b-8 pb-2">Shopping List</h1>
<ul className="flex flex-col gap-2">
{shoppingCart.map((row, i) => {
return (
<ShoppingListRow
key={row.join()}
items={row}
white={i % 2 === 0}
/>
);
})}
</ul>
</div>
</div>
);
}
In order to keep the code neat, I’ve broken it down into a component for 1 shopping list item, 1 shopping list row, and the whole shopping list. I find this is a really good approach for situations like this, as you build your component up from smaller, less complex, building blocks. With this method, the problem goes from figuring out how to map within a map, to just how to map over an array, and doing that in two scenarios.
Here’s what our fancier-looking shopping list looks like:
Instead of being in one big list, the rows are now kept in separate lists, with a bit of fancy styling from TailwindCSS, which you can ready more about here. This approach is useful in a lot of scenarios, such as tables, grids, and more. We could also have easily written the first example using two maps, using a React Fragment, the choice is entirely up to you.
Hopefully with one of these two examples you were able to map through a nested array in your scenario. If so, or if you ran into any issues, feel free to leave a comment down below!
💬 Leave a comment