mrks
mrks

Reputation: 5631

Render table subheader only once in React

I have created the following table in React.

The items I render have either category libraries or softwareComponents as category.

{
  items.map((component: Components) =>
    component.category === "libraries" ? (
      <React.Fragment>
        <tr>
          <th>Libraries</th>
          <th>&nbsp;</th>
        </tr>
        <tr key={component.name}>
          <td>{component.name}</td>
          <td>{component.version}</td>
        </tr>
      </React.Fragment>
    ) : (
      <React.Fragment>
        <tr>
          <th>Software Components</th>
          <th>&nbsp;</th>
        </tr>
        <tr key={component.name}>
          <td>{component.name}</td>
          <td>{component.version}</td>
        </tr>
      </React.Fragment>
    )
  );
}

The problem is that the subheader is rendered now every time but I only want to show it once.

Upvotes: 1

Views: 113

Answers (2)

Tehila
Tehila

Reputation: 1102

You can declare two arrays, one for libraries and one for software. Then, you map the items outside of the return statement and push each table row to the matching array.

And after that you simply return the arrays in the return statement. See codeSandbox

const libraries = [];
const software = [];

items.map((component) => {
    const tableRow = (
      <tr key={component.name}>
        <td>{component.name}</td>
        <td>{component.version}</td>
      </tr>
    );
    component.category === "libraries"
      ? libraries.push(tableRow)
      : software.push(tableRow);
  });
   
  

And your JSX:

return (
    <>
      <tr>
        <th>Libraries</th>
        <th>&nbsp;</th>
      </tr>
      {libraries}
      <tr>
        <th>Software Components</th>
        <th>&nbsp;</th>
      </tr>
      {software}
    </>
  );

Upvotes: 2

Ehsan
Ehsan

Reputation: 195

you can separate item list and write like this :

const libraryList = items.filter((item) => item.category === "libraries");
const others = items.filter((item) => item.category !== "libraries");

export default function App() {
  return (
    <div className="App">
      {libraryList.length && (
        <>
          <tr>
            <th>Libraries</th>
            <th>&nbsp;</th>
          </tr>
          {libraryList.map((component) => (
            <tr key={component.name}>
              <td>{component.name}</td>
              <td>{component.version}</td>
            </tr>
          ))}
        </>
      )}
      {others.length && (
        <>
          <tr>
            <th>Software Components</th>
            <th>&nbsp;</th>
          </tr>
          {others.map((component) => (
            <tr key={component.name}>
              <td>{component.name}</td>
              <td>{component.version}</td>
            </tr>
          ))}
        </>
      )}
    </div>
  );
}

Upvotes: 0

Related Questions