React map to render with row

Viewed 1590

Hi I have an array with 6 element and itterate 3 in each row with map function by dividing the array into three elements and I dont do this without dividing array my code is below

<div
style={{
  width: "100%",
  display: "flex",
  flexWrap: "wrap",
  justifyContent: "space-around",
}}
>
{array1.map((item, index) => {
  return (
      <div className="col-4">
        <img  src={item.icon} />
        <p >{item.title}</p>
        <p >
          {item.description}
        </p>
      </div>
  );
})}
</div>
<div
style={{
  width: "100%",
  display: "flex",
  flexWrap: "wrap",
  justifyContent: "space-around",
}}
>
{array2.map((item) => {
  return (
    <div className="col-4 item-item">
      <img src={item.icon} />
      <p>{item.title}</p>
      <p>
        {item.description}
      </p>
    </div>
  );
})}
</div>

I want to map 3 elements per row and without dividing the 6 elements array to 3 elements thanks for suggestion

4 Answers

You can just use map for this purpose

array.map((element, index) => {
        if (index % 3 === 0)
          return (
            <div className="row">
              <div className="col">{array[index]}</div>
              <div className="col">{array[index + 1]}</div>
              <div className="col">{array[index + 2]}</div>
            </div>
          );
      })

If you decide to change number of elements per row, you can just tweak the values.

Check a working example here

I'd recommend you use this function here to split the array up into chunks. From there you can perform a nested map!

// # Source https://github.com/30-seconds/30-seconds-of-code/blob/master/snippets/chunk.md
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );

console.log(chunk([1, 2, 3, 4, 5,6], 3));
// Output - [[1,2,3],[4,5,6]]

Considering you already know the length of array which is 6. Assuming array name to be "originalArray"

<div
style={{
  width: "100%",
  display: "flex",
  flexWrap: "wrap",
  justifyContent: "space-around",
}}
>
{originalArray.map((item, index) => {
(index<3)?
  return (
      <div className="col-4">
        <img  src={item.icon} />
        <p >{item.title}</p>
        <p >
          {item.description}
        </p>
      </div>
}
   : return( <div className="col-4 item-item">
      <img src={item.icon} />
      <p>{item.title}</p>
      <p>
        {item.description}
      </p>
    </div>)
  );
})}
</div>

I am not sure about performance of this snippet, but you can achieve what you want with reduce instead of map

array.reduce<JSX.Element[]>((rows, item, itemIndex) => {
    const ComponentToRender = <Component />
    if (itemIndex % 3 === 0) {
        rows.push(<Row key={rows.length + 1}>{ComponentToRender}</Row>);
    } else {
        const LastRow = rows[rows.length - 1];
        const cols = [
            ...React.Children.toArray(LastRow.props.children),
            ComponentToRender,
        ];
        rows[rows.length - 1] = <Row key={rows.length + 1}>{cols}</Row>;
    }
    
    return rows;
}, [])

Or just use a CSS grid system to be able to render 3 elements per row. That way you can stick to the simple map.

Related