I want to create a generic table that can map rows of different interfaces.
Let's say I have the following interfaces:
interface Row1{
username: string;
email: string;
}
interface Row2{
firstName: string;
lastName: string;
address: string;
age: string;
}
Now I want to map them in a tbody like this (?):
const rows1: Row1 = [{username: "tester", email: "[email protected]"}, {username: "tester2", email: "[email protected]"}]
const rows2: Row2 = [{firstName: "Bob", lastName: "Bobber", address: "street", age: "22"}, {firstName: "Bill", lastName: "Gates", address: "street2", age: "55"}]
<tbody>
{rows1?.map((row, index) => {
return(
<tr key={index}>
<td>{row.username}</td>
<td>{row.email}</td>
</tr>
)
}}
</tbody>
How can I use the same tbody for both rows1 and rows2, instead of creating two separate tbodies? I.e, reusing the same component.
CodePudding user response:
I guess you want to create only single component but capable to vary the amount of columns based on the given rows and header accordingly.
Here is my solution (hand-written, might have typo).
The TBody component:
interface TBodyProps {
rows: {
[key: string]: string;
}[];
// for denoting what headers should be shown
// and indicating the order of the field
headers: string[];
}
const TBody = ({ rows, headers }: TBodyProps) => {
return (
<tbody>
{
rows.map(row => (
<tr>
{
headers.map(header => (
<td>
{row[header]}
</td>
))
}
</tr>
))
}
</tbody>
);
}
Reuse the component:
return (
<>
<TBody
rows={rows1}
headers={["username", "email"]}
/>
<TBody
rows={rows2}
headers={["firstName", "lastName"]}
/>
</>
)