首页 > 解决方案 > React:将每 3 个组件包装成一个 div

问题描述

我是 React(和 JS)的新手,为了训练我正在尝试重写我已经完成的旧网站。在这个网站上,我展示了 X 产品的列表。对于非常行,有 3 个产品要展示。

我面临一个关于造型的问题。我想使用 flexbox,因此我必须将每 3 个产品包装在一个 div 中。

这是我在渲染一个名为 GiftList 的组件时尝试做的事情:

 render() {
    const { list } = this.state;

    return (
      <div className="GiftsList">
       {
          list.map((item, index) =>
            {
             
              if(index % 3 === 0){<div>}
              <Product />
              if(index % 3 === 0){</div>}
              
            })   
        }
      
      </div>
    );
  }

我也看到了这个建议:How to use if within a map return? 但没有成功。我知道我搞砸了'{'和'('和'return'......但我不明白。有人可以解释我该怎么做吗?

顺便说一句,这是实现我想要的最佳方式吗?像这样 :

<div>
<Product />
<Product />
<Product />
</div>
<div>
<Product />
<Product />
<Product />
</div>
...

非常感谢 !!

标签: reactjsdictionarycomponents

解决方案


AFAIK 你不能有条件地在 array::map 中渲染打开/关闭标签,在 JSX 中映射的每个元素都需要是一个完整的节点。

您可以通过首先将数组拆分为块数组来实现分组,然后映射外部块数组内部块数组。

将数组拆分为长度为 3 的块有这个 解决方案(已关闭但在此处指出),尽管这需要在渲染之前进行一些“预处理”。

给定一些数据数组[0..15]

const data = [...Array(16).keys()];

您可以复制到一个临时数组并拼接出 3 个元素的块

const data2 = [...data];
const groupedData1 = [];
while(data2.length) {
  groupedData1.push(data2.splice(0, 3));
}

const data = [...Array(16).keys()];

const data2 = [...data];
const groupedData1 = [];
while(data2.length) {
  groupedData1.push(data2.splice(0, 3));
}
console.log(groupedData1);

如果您更喜欢 JSX 中常用的功能更强大的内联方法。这里使用 array::reduce 将数据数组缩减为 3 个块,最后的 array::filter 用于清除任何结束的空数组(就像块长度除以数据长度的情况一样。

const groupedData2 = data
  .reduce((groups, curr) => {
    const arr = groups[groups.length - 1];
    arr.push(curr);
    if (arr.length === 3) groups.push([]);
    return groups;
  }, [[]])
  .filter((chunk) => chunk.length);

const data = [...Array(16).keys()];

const groupedData2 = data
  .reduce((groups, curr) => {
    const arr = groups[groups.length - 1];
    arr.push(curr);
    if (arr.length === 3) groups.push([]);
    return groups;
  }, [[]])
  .filter((chunk) => chunk.length);

console.log(groupedData2);

现在渲染分块数组

data.<inlineChunkProcess>.map((group, i) => (
  <div key={i}>
    {group.map((product, i) => (
      <Product key={i} value={product} />
    ))}
  </div>
))

这是一个高级概述,实际上您不希望将数组索引用作反应键。在对数据进行分块/分组时,您需要为该组生成一个唯一 ID ,并且您希望每个产品都有自己的唯一 ID(希望已经是这种情况)。如果/当您需要从列表中添加或删除任何单个产品时,这将有所帮助。

例子:

const Group = () => ({
  id: uuidv4(),
  data: []
});

...

{list
  .reduce(
    (groups, curr) => {
      const group = groups[groups.length - 1];
      group.data.push(curr);
      if (group.data.length === 3) {
        groups.push(new Group());
      }
      return groups;
    },
    [new Group()]
  )
  .filter(({ data }) => data.length)
  .map(({ data, id }, i) => (
    <div key={id} className="myDiv">
      Group Id: {id}
      <div>
        {data.map(({ id, value }, i) => (
          <Product key={id} value={value} />
        ))}
      </div>
    </div>
  ))}

编辑 react-wrap-every-3-components-into-a-div


推荐阅读