Home > database >  React typescript generic mapping in table
React typescript generic mapping in table

Time:08-12

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"]}
    />
  </>
)
  • Related