1
votes

Comment mapper des éléments en deux colonnes de tableau, deux éléments par ligne?

J'essaie de faire ressembler le résultat final à, (suivant cet exemple ):

const arrayOfComponents = [
  { name: 'abc', key: 'value1'},
  { name: 'def', key: 'value2' },
  . . .
]

Le problème est que je n'arrive pas à comprendre comment faire cela dans React. La fonction de carte d'origine ressemble actuellement à:

<div className="main">
  {
    arrayOfComponents.map((({ name }), index) => (
      <div className={index % 2 === 0 ? 'row' : ''}>
        <div className="column">
          <Component
            key={`${index}-${name}`}
            label={name}
          />
        </div>
      </div>
    ))
  }
</div>

J'ai essayé de faire quelque chose comme,

<div className="main">
  {
    arrayOfComponents.map((({ name }), index) => (
      <Component
        key={`${index}-${name}`}
        label={name}
      />
    ))
  }
</div>

Mais cela n'a pas été le cas t semble fonctionner, et si c'est le cas, cela semble compliqué. Comment puis-je procéder?

arrayOfComponents ressemble à quelque chose comme

<style>
* {
  box-sizing: border-box;
}

.column {
  float: left;
  width: 50%;
  padding: 10px;
  height: 300px;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}
</style>

<div class="row">
  <div class="column">
    <Component />
  </div>
  <div class="column">
    <Component />
  </div>
</div>


5 commentaires

À quoi ressemble arrayOfComponents ?


OP mis à jour, c'est juste un tableau régulier d'objets.


Et vous voulez qu'ils soient placés dans col1 et 2 dans l'ordre alterné?


Oui, c'est ça.


S'il y a plus de deux colonnes dans une ligne , ils seront automatiquement enveloppés car ils ont une largeur: 50% définie.


3 Réponses :


2
votes

Il vous suffit de mapper sur le tableau et de renvoyer le composant enveloppé dans un div avec className de colonne em > comme ceci:

<div class="row bg">
  <div class="column">
    <h2>Column 1</h2>
    <p>Some text..</p>
  </div>
  <div class="column">
    <h2>Column 2</h2>
    <p>Some text..</p>
  </div>
</div>

<div class="bg">
  <div class="column">
    <h2>Column 1</h2>
    <p>Some text..</p>
  </div>
  <div class="column">
    <h2>Column 2</h2>
    <p>Some text..</p>
  </div>
</div>

* {
  box-sizing: border-box;
}

/* Create two equal columns that floats next to each other */
.column {
  float: left;
  width: 50%;
  padding: 10px;
}

/* Clear floats after the columns */
.row:after {
  content: "";
  display: table;
  clear: both;
}

.bg{
  background:orange;
  border: 2px solid red;
  margin: 0 auto 100px;
}
<div className="main">
  <div className="row">
   {
    arrayOfComponents.map(({name},index) => (
        <div className="column">
          <Component
            key={`${index}-${name}`}
            label={name}
          />
        </div>
    ))
   }
  </div>
</div>

J'espère que cela vous aidera!


4 commentaires

Mais cela ne rend qu'un seul élément div avec la classe row . Que faire si j'ai 100 éléments dans arrayOfComponents et que j'ai besoin de 50 div avec la classe row (car il y a 2 éléments par ligne )?


@MikeK Vous n'avez pas besoin de plusieurs lignes. L'un est bien. Les colonnes s'aligneront automatiquement. Essayez d'incréter les objets dans le tableau.


Cela a parfaitement fonctionné. Pouvez-vous expliquer en un ou deux mots pourquoi je n'ai pas besoin de plusieurs lignes, s'il vous plaît?


@MikeK Donc, c'est essentiellement des flottants css. Il faut donc avoir un élément container qui efface le flottant de la classe column ... ici ce container est la row . Un seul est nécessaire. float rompt le flux normal du document et vous devez l'effacer pour que le flux redevienne normal. Voir l'exemple que j'ai fait. La classe bg a une bordure et un arrière-plan. La classe div avec ligne se développe jusqu'à ce que les colonnes, mais celle sans classe ligne se brise. En savoir plus sur les flotteurs ici: css-tricks.com/all-about-floats



0
votes

Si vous avez spécifiquement besoin d'éléments row supplémentaires, vous pouvez utiliser un rendu conditionnel comme celui-ci. Cela créerait une nouvelle ligne après 2 colonnes.

<div className="main">
  {
    arrayOfComponents.map(({ name }, index) => index%2!=0?null:(
      <div className="row">
        <div className="column">
          <Component
            key={`${index}-${name}`}
            label={name}
          />
        </div>
        {arrayOfComponents[index+1] && (
        <div className="column">
          <Component
            key={`${index+1}-${arrayOfComponents[index+1].name}`}
            label={arrayOfComponents[index+1].name}
          />
        </div>
        )}
      </div>
    ))
  }
</div>


0 commentaires

0
votes

Vous pouvez utiliser la réduction pour diviser vos données:

const rows = arrayOfComponents.reduce((acc, rec, index) => {
    if (index % 2 === 0) {
      return [...acc, [rec]]
    }
    acc[acc.length - 1] = [...acc[acc.length - 1], rec]
    return acc
  }, [])


const Component = (props) => {
  return <div>
    <h2>{props.item.name}</h2>
    <p>{props.item.key}</p>
  </div>
}

const TodoApp = () => {
  return rows.map((row, index)=>{
    return <div key={index}>{
      row.map((col) => <div className="column" key={col.name}><Component item={col}/></div>)
    }</div>
  })
}

Voir l'exemple complet dans l'aire de jeux: https://jsfiddle.net/denisstukalov/ut8x9Lkq/21/#&togetherjs=Q7jLIOHHOP


0 commentaires