【问题标题】:React : wrap every 3 components into a divReact:将每 3 个组件包装成一个 div
【发布时间】:2020-09-01 21:04:19
【问题描述】:

我是 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>
...

非常感谢!!

【问题讨论】:

    标签: reactjs dictionary components


    【解决方案1】:

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

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

    将数组分割成长度为 3 的块有 this solution(已关闭但指向 here),尽管这需要在渲染前进行一些“预处理”。

    给定一些数据数组[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>
    ))
    

    这是一个高级概述,实际上您不希望将数组索引用作反应键。在对数据进行分块/分组时,您需要为 that 组生成一个唯一 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>
      ))}
    

    【讨论】:

    • 哇!!非常感谢,这正是我想知道的。我会努力并尝试以这种方式实现它。感谢您为回答我付出的所有努力和时间!!
    • @ldvc.dpy 欢迎。如果您发现此答案有帮助,请点赞。如果它有助于解决您的问题,那么也请接受作为答案。
    【解决方案2】:

    按照您目前的方式,这将在打开和关闭 &lt;div&gt;s 中包含三分之一的 &lt;Product /&gt;。您希望在余数为 0 时返回一个开始 &lt;div&gt; 标签,在余数为 2 时返回一个结束 &lt;/div&gt;

    list.map((item, index) => (
      {index % 3 === 0 ? <div> : ''}
      <Product />
      {index % 3 === 2} ? </div> : ''}
    )
    

    【讨论】:

    • 确实感谢您的更正!问题是即使使用您的代码我也有解析错误。当我将 if 放入地图时,一切都出错了。你的答案也一样......我不明白为什么
    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 2018-02-23
    • 2022-01-24
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多