Most web applications always have one way or the other to display large data sets on their web page, and the most common one is using tables. Tables are extremely useful to displaying large sets of data, and you can add filtering functionality to it also, not like the filtering is tied to the tables anyways.
So recently after joining klen, one of the things I had to do as a frontend developer was to create reusable components for most of the components on the application. This article is about creating reusable table components, so lets cut the chase.
My Initial table component set up
Before joining Klen, I had a table component that I use mostly for my code project, more like a base structure for the react, then you can update the styles to make it look exactly like whatever the designer designs. My table component structure is like so
<table className="table">
<thead className="headBg">
<tr>
{headers.map(header => {
return (
<th scope="col" key={header}>
{header}
</th>
);
})}
</tr>
</thead>
<tbody>
{data.map(datum => {
return (
<tr key={datum.id} onClick={() => console.log(datum.id)}>
<td>#{datum.id}</td>
<td className="d-flex justify-content-center align-items-center customer--details">
<img src={datum.image} alt="" />
<span>
{datum.firstname} {datum.lastname}
</span>
</td>
<td>#{datum.transactionId}</td>
<td>{datum.name}</td>
<td>N{datum.amount}</td>
<td className="d-flex justify-content-center align-items-center">{this.renderStatusTag(datum.status)}</td>
<td>{moment(datum.createdAt).format("DD-MM-YYYY")}</td>
<td>{moment(datum.createdAt).format("h:mm a")}</td>
</tr>
);
})}
</tbody>
</table>
the above code snippet is how I used to write my table component. It basically works this way,
- Pass an array of string for the header
- pass an array of object for the table list item
and inside the table component its self, I loop through the two arrays to render their individual data.
and then it's imported like so
<AppTable
headers={['header title 1', 'header title 2']}
data={data}
/>
wherever I want to use.
This worked well at a point, but the component is restricted because of the following
- That the component knows the kind of data to expect
- It's hardcoded.
- Too much copying and pasting to make the table render the exact data for different types of table
All these I have noticed with the current way of writing my table component, but I was too lazy to change it, so after joining klen, I made up my mind to update my table component.
The following things are what I considered while refactoring the component
- What every data that is being passed, the table should be able to render the table row with its appropriate table data
- The table must be dynamic
Table data can be dynamic
Whatever data I pass to this table, it should render it.
for instance, I could have any of the following
const earningsData = [
{
id: 23123,
name: 'Jude abaga',
date: 1237682923189813,
amount_paid: '4560000'
},
{
id: 23123,
name: 'Jude Gideon',
date: 12376829231189813,
amount_paid: '560000'
},
]
or, another set of data
const userData = [
{
id: 23123,
name: 'Jude abaga',
email: 'jude.abaga@abaga.com'
date: 1237682923189813,
status: 'pending'
},
{
id: 23128,
name: 'Dev abaga',
email: 'devabaga@abaga.com'
date: 111237682923189813,
status: 'verified'
},
]
Whatever kind of data I am passing as the data prop, it should be able to render the table row without breaking. so how did I achieve this? below is a code snippet
<tbody>
{data.map((datum, index) => {
return (
<tr key={datum.id}>
{Object.keys(headers).map((header, index) => {
<td key={index}>
<span>{datum[header]}</span>
</td>
})}
</tr>
);
})}
</tbody>
The single most important line of code in the above snippet is this one below
Object.keys(headers).map((header, index))
Now my table component now has to parts to it, which are
Remember my
<AppTable headers={[]} data={data} />
takes a headers props, so what I did, was to convert the headers prop from an array to an object, this way I can easily map an item in the data array to the headers. So what this does is, it returns the keys in the headers object and maps through it, then look for the individual item in the data object
Top comments (5)
Great soluciΓ³n. Thanks
I'm glad you liked it.
Great solution. Thanks!!!
thanks
thanks for this solution, I want to know if i want to add any specific style to any field then how should i do it.
e.g: for status i want to change text color to any specific color.