Search code examples
reactjscomponentsiterationarray.prototype.map

create flex component with a map in React


I have some data in an array of objects I want to put in different containers in pairs.

This is the structure of the dummy data array:

const projects = [
  {
    title,
    text,
    ...
  },
  {
    title,
    text,
    ...
  },
  {
    title,
    text,
    ...
  },
  {
    title,
    text,
    ...
  },
  ...
]

This is my component:

const Home = () => {
  return (
    <HomePage className="pageContainer">
      <div className="projects" style={display: 'flex'}>
        {projects.map( (project, index) => {
            return <Project key={index} project={project} />
        })}
      </div>
    </HomePage>
  )
}

Now this works perfectly fine, but it gives me the following html:

<div class="projects">
  <div class="projectCard">
    <!-- content of project[0] -->
  </div>
  <div class="projectCard">
    <!-- content of project[1] -->
  </div>
  <div class="projectCard">
    <!-- content of project[2] -->
  </div>
  <div class="projectCard">
    <!-- content of project[3] -->
  </div>
  ...
</div>

Ideally, I'd like the following:

<div class="projects">
  <div class="projectRow">
    <div class="projectCard">
      <!-- content of project[0] -->
    </div>
    <div class="projectCard">
      <!-- content of project[1] -->
    </div>
  </div>
  <div class="projectRow">
    <div class="projectCard">
      <!-- content of project[2] -->
    </div>
    <div class="projectCard">
      <!-- content of project[3] -->
    </div>
  </div>
  ...
</div>

I could probably do a hacky way, just as below, but there must be a better way (this works fine as I only have four projects currently)??

const Home = () => {
  return (
    <HomePage className="pageContainer">
      <div className="projects">
        <div className="projectRow">
          {projects.map( (project, index) => {
            if (index % 2 === 1) {
              return <Project key={index} project={project} />
            }
          })}
        </div>
        <div className="projectRow">
          {projects.map( (project, index) => {
            if (index % 2 !== 1) {
              return <Project key={index} project={project} />
            }
          })}
        </div>
      </div>
    </HomePage>
  )
}

Solution

  • You can do something like this:

    const Home = () => {
        const projects: unknown[] = [1, 2, 3, 4, 5, 6, 7, 8];
    
        const groupLength = 2;
    
        if (projects.length % groupLength !== 0) {
            // means projects can not be divided into groups  
            // of "groupLength" without leftovers
            return null;
        }
    
        const groupsNumber = projects.length / groupLength;
    
        return (
            <HomePage className="pageContainer">
                <div className="projects">
                    {[...Array(groupsNumber).keys()].map((_, groupIndex) => (
                        <div className="projectRow">
                            {projects
                                .slice(groupIndex * groupLength, (groupIndex + 1) * groupLength)
                                .map((project, index) => (
                                    <Project key={groupIndex * groupLength + index} project={project} />
                                ))}
                        </div>
                    ))}
                </div>
            </HomePage>
        );
    };