snippetjavascriptTip
Mapping data structures to React components
Viewed 0 times
componentsdatastructuresmappingreact
Problem
Have you ever wanted to quickly transform an array into a table or an object into a tree view? One of the benefits of React is that you can easily map data structures to components, even customizing them to your needs.
The simplest mapping is an array of primitives to a list of elements. All you really need is
A very similar use-case is mapping an array of primitives to a table. The process is almost identical, but this time you render each item as a
For more complex structures, such as arrays of objects, you'll need a more sophisticated component. Instead of rendering each item as a
To get the keys and iterate over them, you'll combine
The simplest mapping is an array of primitives to a list of elements. All you really need is
Array.prototype.map() to render each item as a <li> element. In addition to that, you should use a key prop to help React identify each item. Finally, wrap the result in an <ol> or <ul> element, depending on whether you want an ordered or unordered list.A very similar use-case is mapping an array of primitives to a table. The process is almost identical, but this time you render each item as a
<tr> element with two <td> children. The first <td> contains the index of the item, while the second one contains the item itself.For more complex structures, such as arrays of objects, you'll need a more sophisticated component. Instead of rendering each item as a
<tr> element, you'll need to render each object as a <tr> element with a <td> for each key in the object. This way, you can create a table with rows dynamically created from an array of objects and a list of property names.To get the keys and iterate over them, you'll combine
Object.keys(), Array.prototype.filter(), Array.prototype.includes(), and Array.prototype.reduce(). This will produce a filteredData array, containing all objects with the keys specified in propertyNames.Solution
const DataList = ({ isOrdered = false, data }) => {
const list = data.map((val, i) => <li key={`${i}_${val}`}>{val}</li>);
return isOrdered ? <ol>{list}</ol> : <ul>{list}</ul>;
};
const names = ['John', 'Paul', 'Mary'];
ReactDOM.createRoot(document.getElementById('root')).render(
<>
<DataList data={names} />
<DataList data={names} isOrdered />
</>
);A very similar use-case is mapping an array of primitives to a table. The process is almost identical, but this time you render each item as a
<tr> element with two <td> children. The first <td> contains the index of the item, while the second one contains the item itself.For more complex structures, such as arrays of objects, you'll need a more sophisticated component. Instead of rendering each item as a
<tr> element, you'll need to render each object as a <tr> element with a <td> for each key in the object. This way, you can create a table with rows dynamically created from an array of objects and a list of property names.To get the keys and iterate over them, you'll combine
Object.keys(), Array.prototype.filter(), Array.prototype.includes(), and Array.prototype.reduce(). This will produce a filteredData array, containing all objects with the keys specified in propertyNames.> [!CAUTION]
>
> This component does not work with nested objects and will break if there are nested objects inside any of the properties specified in
propertyNames.Code Snippets
const DataList = ({ isOrdered = false, data }) => {
const list = data.map((val, i) => <li key={`${i}_${val}`}>{val}</li>);
return isOrdered ? <ol>{list}</ol> : <ul>{list}</ul>;
};
const names = ['John', 'Paul', 'Mary'];
ReactDOM.createRoot(document.getElementById('root')).render(
<>
<DataList data={names} />
<DataList data={names} isOrdered />
</>
);const DataTable = ({ data }) => {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{data.map((val, i) => (
<tr key={`${i}_${val}`}>
<td>{i}</td>
<td>{val}</td>
</tr>
))}
</tbody>
</table>
);
};
const people = ['John', 'Jesse'];
ReactDOM.createRoot(document.getElementById('root')).render(
<DataTable data={people} />
);const MappedTable = ({ data, propertyNames }) => {
let filteredData = data.map(v =>
Object.keys(v)
.filter(k => propertyNames.includes(k))
.reduce((acc, key) => ((acc[key] = v[key]), acc), {})
);
return (
<table>
<thead>
<tr>
{propertyNames.map(val => (
<th key={`h_${val}`}>{val}</th>
))}
</tr>
</thead>
<tbody>
{filteredData.map((val, i) => (
<tr key={`i_${i}`}>
{propertyNames.map(p => (
<td key={`i_${i}_${p}`}>{val[p]}</td>
))}
</tr>
))}
</tbody>
</table>
);
};
const people = [
{ name: 'John', surname: 'Smith', age: 42 },
{ name: 'Adam', surname: 'Smith', gender: 'male' }
];
const propertyNames = ['name', 'surname', 'age'];
ReactDOM.createRoot(document.getElementById('root')).render(
<MappedTable data={people} propertyNames={propertyNames} />
);Context
From 30-seconds-of-code: data-mapping-components
Revisions (0)
No revisions yet.