How to make 3 column grid with map function react

Viewed 2146

I have some cards, I want to make it looks like this

[] [] []
[] [] []
[] [] []
...
...

I have a problem rendering the item with map function. I already try this but it doesn't work. For every index if the index divisible by 3 I wanted to make new row. How I can do that?

                {products.map((val, index) => (
                    { index%3 == 0 ? <div className="row mx-auto"> : null}
                    <Card>
                      {val.description}
                    </Card>
                    { index%3 == 0 ? </div> : null}
                ))}

Any help would be appreciated.

3 Answers

Issue

You can't conditionally render open/close tags like this.

Solution

Chunk up your array into an array of arrays and map the rows and then map the columns.

Example chunking function:

const arrayChunk = (arr, n) => {
  const array = arr.slice();
  const chunks = [];
  while (array.length) chunks.push(array.splice(0, n));
  return chunks;
};

Example mapping:

{arrayChunk(products, 3).map((row, i) => (
  <div key={i} className="row mx-auto">
    {row.map((col, i) => (
      <span key={i}>[{col}]</span>
    ))}
  </div>
))}

const arrayChunk = (arr, n) => {
  const array = arr.slice();
  const chunks = [];
  while (array.length) chunks.push(array.splice(0, n));
  return chunks;
};

function App() {
  return (
    <div className="App">
      {arrayChunk([...Array(9).keys()], 3).map((row, i) => (
        <div key={i} className="row mx-auto">
          {row.map((col, i) => (
            <span key={i}>[{col}]</span>
          ))}
        </div>
      ))}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <App />,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

You may try on this if you wish to have row mx-auto class.

{products.map((val, index) => {
    let card = <Card>{val.description}</Card>
    return (index%3 == 0 ? <div className="row mx-auto">{card}</div> : {card})
  }
)}

Alternatively, you may use col-4 directly on your <div>. It is very simple.

You can create a div with class col-*-4. And in this div, use map function to loop data

Related