skip to Main Content

Currently I only get the first value of each object inside itemList:

name description details
1 2 3
itemList = [
  {
    id: 1,
    name: "item1",
    description: "description1",
    details: "detail1"
  },
  {
    id: 2,
    name: "item2",
    description: "description1",
    details: "detail2"
  },
  {
    id: 3,
    name: "item3",
    description: "description1",
    details: "detail3"
  }
];

function Items() {
  const handleRender = () => {
    return itemList.map((item) => {
      for (let entry in item) {
        return (
          <div className="grid-item" key={item.id}>
            {item[entry]}
          </div>
        );
      }
    });
  };

  return (
    <div className="grid-container">
      <div className="grid-item">name</div>
      <div className="grid-item">description</div>
      <div className="grid-item">details</div>

      {handleRender()}
    </div>
  );
}

I tried to loop in different ways, but I either get one div with all the itemList entries as one grid-item, or only the first value of each object.

I want to have three columns:

name description details
item1 description1 details1
item2 description2 details1
item3 description3 details1

How can I achieve this?

Is it even possible using CSS grid?

4

Answers


  1. You can use HTML table to produce this type of output
    For example

     <table>
            <thead>
              <tr>
                <th>name</th>
                <th>description</th>
                <th>details</th>
              </tr>
            </thead>
            <tbody>
              {
                itemList.map((item) => {
                  return <tr>
                    <td>{item.name}</td>
                    <td>{item.description}</td>
                    <td>{item.details}</td>
                  </tr>
                })
              }
    
            </tbody>
          </table>
    
    Login or Signup to reply.
  2. We can refactor handleRender
    something like this

     const handleRender = () => {
        return itemList.map((item) => {
          return Object.keys(item).map((key, index) => {
            return (
              <div className="grid-item" key={item.id}>
                {item[key]}
              </div>
            );
          });
        });
      };
    
    Login or Signup to reply.
  3. You can use a single map function to display your items. And use the properties to display the ‘cells’.

    export default function Items() {
      return (
        <div className="grid-container">
          <div className="grid-item">name</div>
          <div className="grid-item">description</div>
          <div className="grid-item">details</div>
          {itemList.map((item) => {
            return (
              <>
                <div className="grid-item">{item.name}</div>
                <div className="grid-item">{item.description}</div>
                <div className="grid-item">{item.details}</div>
              </>
            );
          })}
        </div>
      );
    }
    

    Your css could look something like this.

    .grid-container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
    }
    
    Login or Signup to reply.
  4. Instead of a loop, you can use Object.entries to get an array of the properties for a JavaScript object, then outputting the td elements for a table is as straightforward as the technique that you already successfully used to .map its rows.

    You can also follow the same technique to extract the column names for the header. Just get them from the first row. Note, this doesn’t work for an empty table: with no rows, you won’t get a header. It’s also sensitive to property order, so be careful to normalize your data.

    You have omitted the id property from your example table, so I’ve used .filter to remove it here as well.

    const itemList = [
      {
        id: 1,
        name: "item1",
        description: "description1",
        details: "detail1"
      },
      {
        id: 2,
        name: "item2",
        description: "description1",
        details: "detail2"
      },
      {
        id: 3,
        name: "item3",
        description: "description1",
        details: "detail3"
      }
    ];
    
    function Table(props) {
      return (
        <table>
          <thead>
            <tr>
              {
                Object.entries(props.rows[0])
                  .filter(([key, value]) => key !== 'id')
                  .map(([key, value]) => (<th key={key}>{ key }</th>))
              }
            </tr>
          </thead>
          <tbody>
            {
              props.rows.map(row => (
                <tr>
                  {
                    Object.entries(row)
                      .filter(([key, value]) => key !== 'id')
                      .map(([key, value]) => (<td key={key}>{ value }</td>))
                  }
                </tr>
              ))
            }
          </tbody>
        </table>
      );
    }
    
    ReactDOM.render(
      <Table rows={ itemList } />,
      document.getElementById("root")
    );
    table { border-collapse: collapse; }
    table, th, td { border: 1px solid; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search