React Tabular Data
May 30, 2022
When I first came to JSX in React I expected to find components that template repeating rows in a JSX table similar in format to what is finally rendered. I envisioned something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<DataGrid rows={rows}>
<Header>
<Th width={'30%'} sortable>Column 0</Th>
<Th width={'30%'} sortable>Column 1</Th>
<Th width={'20%'}>Column 2</Th>
<Th width={'20%'}>Column 3</Th>
</Header>
<RowTemplate>
<Td>{col0}</Td>
<Td>{col1}</Td>
<Td>{col2}</Td>
<Td>{col3}</Td>
</RowTemplate>
<DataGrid>
A lot of what you’ll find with popular React table components require an external definition of your columns:
1
2
3
4
5
6
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 70 },
{ field: 'firstName', headerName: 'First name', width: 130 },
{ field: 'lastName', headerName: 'Last name', width: 130 },
{ field: 'age', headerName: 'Age', type: 'number', width: 90 },
];
These columns are then provided as a prop to the library component.
1
2
3
4
5
6
7
8
// use DataGrid
<DataGrid
rows={rows} // user data
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
/>
Benefits:
- easy to implement.
- definable from remote payloads.
Drawbacks:
- contract of the columns field requires documentation (or typescript).
- visual model of final rendering not as clear.
To figure out if the idea is even possible I decided to start small with a unordered list:
1
2
3
<List rows={rows}>
<Items/>
</List>
The component receives a the row data and clones the children as a template for row of data:
1
2
3
4
5
6
7
8
9
function List({rows, children}) {
return (
<Ul>
{rows.map((el, idx) =>
(<Li key={idx}>{React.Children.map(children, c => React.cloneElement(c, el))}</Li>)
)}
</Ul>
);
}
This component requires the user specify the item list and input props as a component:
1
2
3
4
5
6
7
8
9
10
function Items({id, firstName, lastName, age}) {
return (
<>
<span>{ id }</span>
<span>{ firstName }</span>
<span>{ lastName }</span>
<span>{ age }</span>
</>
);
}
The implementation isn’t as representational as I would hope but it is closer to my initial desire.
Benefits:
- Closer to rendered HTML structure.
- Greater control over items.
Drawbacks:
- Potential for unequal header and cell count.
- More boilerplate.
Is there a name for this pattern in the React community? Is this something library consumers would like to see more of?
Drop a comment and let me know what you think.
tags: [ javascript react ]