Introduction
Recently I had a need to add table rows dynamically when a user clicks on a link in the Table cell. I wanted to look it like, I can expand and collapse the section such that, user can see the additional details on demand.
This short post is to talk about the same so that, it could be useful to any of you when the need arises.
TL;DR
I have created a Stackblitz project to share and demonstrate this. The final outcome looks like this:
Here is the Stackblitz project to look into the code in details:
The code is in GitHub as well: https://github.com/atapas/react-add-table-dynamic-row
A bit of Explanation
If you are familiar with react, the code flow should be easy to understand. I would like to explain some portion of the code here:
useState Hook to track what has been expended
useState
hook from React helps us to keep track of a couple of state variables,
- Keep track of all the expanded rows. It is a simple array that holds the id of the expanded rows.
// State variable to keep track of all the expanded rows. Example, [1, 2, 3] // By default, nothing expanded. Hence initialized with an empty array. const [expandedRows, setExpandedRows] = useState([]);
- Keep track, if the row is currently expanded.
// State variable to keep track which row is currently expanded. Example, {1: true} const [expandState, setExpandState] = useState({});
Simple array operations to add/remove the table row
The includes()
method determines whether an array contains a specified element. This method returns true if the array contains the element, and false if not.
The code below determines if a particular row is expanded by finding if the id has been included in the array.
const isRowExpanded = currentExpandedRows.includes(userId);
As we are toggling the show-hide on clicking a link, we need the logic below. If the row is expanded, we are here to hide it. Hence remove it using the filter()
method. Otherwise, just add it using the concat()
method.
// If the row is expanded, we are here to hide it. Hence remove
// it from the state variable. Otherwise, add to it.
const newExpandedRows = isRowExpanded ?
currentExpandedRows.filter(id => id !== userId) :
currentExpandedRows.concat(userId);
Finally the rendering part
Finally, we need to render the dynamic row based on the condition, if the current row is expanded.
{
expandedRows.includes(user.id) ?
<tr>
<td colspan="6">
<div>
ADD WHATEVER YOU WANT TO RENDER
</div>
</td>
</tr> : null
}
If you enjoyed this article or found it useful let's connect. You can find me on Twitter(@tapasadhikary) sharing thoughts, tips, and code practices. My GitHub(atapas) page lists useful side-projects that you may find useful too.