I’m trying to recreate html table functionality in React Native and I just cannot figure this out.
I have 1 column for item name (short), and another for item description (potentially very long).
I want the first column to take up only as much space as it needs and the second column to flex and then text-wrap when it runs out of room. That part’s easy, but then the items in the first column all have different widths. And if I make the columns first instead in order to solve that problem, then getting the corresponding items in the first column to flex vertically to stay aligned is tripping me up. HTML tables do this effortlessly. Why is it so hard in Native?
Is there really no way to do a truly flexible table in this language?
I’ve tried different variations on flex, but I don’t want it to be a fixed width or ratio for either column, since I want to leave the option for font sizes later, which would break it.
react-native-paper
fails because DataTable.Cell
doesn’t allow for multiline, and adding in the functionality messes with the alignment, bringing me right back to where I started.
EDIT: In html, I would do it like this:
<html>
<head>
<style>
td:first-child {white-space: nowrap; }
</style>
</head>
<body>
<table>
<tr>
<td>
I am some data!
</td>
<td>
Two households, both alike in dignity, in fair Verona, where we lay our scene, from ancient grudge break to new mutiny, where civil blood makes civil hands unclean.
</td>
</tr>
<tr>
<td>
I'm data too!
</td>
<td>
From forth the fatal loins of these two foes, a pair of star-cross'd lovers take their life; whose misadventured piteous overthrows do with their death bury their parents' strife.
</td>
</tr>
<tr>
<td>
I am also some data!
</td>
<td>
The fearful passage of their death-mark'd love, and the continuance of their parents' rage, which, but their children's end, nought could remove, is now the two hours' traffic of our stage; the which if you with patient ears attend, what here shall miss, our toil shall strive to mend.
</td>
</tr>
</table>
</body>
</html>
resulting in:
2
Answers
Okay, I think I got pretty much the functionality I wanted. There's probably a way more extensible way to do this, and this is probably wildly inefficient, but it seems to work.
The gist is that I can use a state variable to store the desired width of each cell, and then in
onLayout
, I can callsetColWidth
to update that variable whenever the layout changes. Then, I can just use style to set the minimum width to the width of the biggest cell.Then there's an array that determines whether a given column gets shrunk to allow room for others.
Finally, I can call
alignItems
in the parentView
to shrink-wrap the tables to the minimum size that fits the dataHere's how it looks with some example data from my project (the yellow boxes are the tables using this code):
Android emulator showing the working code
Right now, the only problem I can see is that it doesn't update when rotating from landscape to portrait (but portrait to landscape works fine???).
You could create a component called
Table
which represents the table itself and one component calledTableRow
which represents one row of the table.and
in my opinion using
flex: 1
instead ofwidth: 'auto'
looks better but of course i don’t know what your prerequisites are.To fill the Table with data you need pass the table component an array of items. To do this modify the Table component
Now you can do the following:
This will fill your table with data.