React:将每 3 个组件包装成一个 div [英] React : wrap every 3 components into a div

查看:19
本文介绍了React:将每 3 个组件包装成一个 div的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我遇到了关于样式的问题.我想使用 flexbox,因此我必须将每 3 个产品包装在一个 div 中.

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

 渲染() {常量 { 列表 } = this.state;返回 (<div className="GiftsList">{list.map((item, index) =>{如果(索引 % 3 === 0){

}<产品/>if(index % 3 === 0){

}})}</div>);}

我也看到了这个建议:

I am new to React (and JS) and in order to train I am trying to rewrite an old website I've done. On this website I display a list of X products. for very row there are 3 products to display.

I face an issue about styling. I want to use flexbox and thus I have to wrap every 3 products in a div.

This is what I try to do in the render of a component called 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>
    );
  }

I also saw this advice : How to use if within a map return? but without success. I know I messed up with the '{' and '(' and 'return' ... but I don't get it. Can someone explain me how to do it ?

By the way, is this the best way to achived what I want ? like this :

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

Thanks a lot !!

解决方案

AFAIK you can't conditionally render opening/closing tags within array::map in react, each element mapped in JSX needs to be a complete node.

You can achieve the grouping by first splitting your array into an array of chunks, then map both the outer array of chunks and the inner chunk arrays.

Splitting an array into length-3 chunks there is this solution (closed but points here), though this would require some "pre-processing" before rendering.

Given some data array [0..15]

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

You could copy into a temp array and splice off chunks of 3 elements

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);

If you prefer the more functional, in-line approach commonly used in JSX. Here an array::reduce is used to reduce the data array into chunks of 3, and the final array::filter is used to clear out any ending empty array (as is the case when the chunk length divides the data length.

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);

Now to render the chunked arrays

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

This is a high-level overview, in actuality you'll not want to use the array index as a react key. When chunking/grouping your data you'll want to generate a unique id for that group and you'll want each product to have its own unique id (which hopefully is already the case). This will help if/when you need to add or remove any single product from your list.

Example:

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:将每 3 个组件包装成一个 div的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆