React:每隔4列渲染一个新行

时间:2017-02-22 12:27:27

标签: twitter-bootstrap reactjs

我正在使用react,我希望render每隔一列新增一行。

我的代码:

function Product(props) {
  const content = props.products.map((product) => (
        <div className="row" key={product.id}>       
          <article key={product.id} className="col-md-3"></article>
        </div> )
  );
  return (
    <div>
        {content}
    </div>
  );
}

我通过传递一个看起来像这样的条件尝试了这个方法:

if (product.id % 4 == 1),在列周围,但它不起作用......

这就是我想要发生的事情:

<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
</div>

7 个答案:

答案 0 :(得分:8)

  1. 将您的产品分组为(最多)4个元素,即

    [1,2,3,4,5,6,7,8] => [ [1, 2, 3, 4], [5, 6, 7, 8 ] ]

  2. 迭代组以生成行,并在内部循环中迭代项目以显示列

  3. 要计算每行4个项目的行数,请使用Math.ceil(props.products.length / 4)。然后创建一个行数组。给定2行(8个项目):Array(2)。由于您无法map未初始化元素数组,因此您可以使用扩展语法:[...Array(2)]返回[ undefined, undefined ]

    现在,您可以将这些undefined条目映射到行中:对于每一行,从产品中获取4个元素:[ undefined, undefined ].map( (row, idx) => props.products.slice(idx * 4, idx * 4 + 4) ) )编辑注释更改为slice,因为{ {1}}改变原始数组)。结果是一个数组数组(项目行)。

    您可以迭代行,并在每次迭代内迭代给定行中的项目。

    https://jsfiddle.net/dya52m8y/2/

    splice

答案 1 :(得分:7)

这样写:

function Product(props) {
  let content = [];
  props.products.forEach((product, i) =>{
      if((i+1) % 4 == 0){
        content.push(
          <div className="row" key={product.id}>       
            <article key={product.id} className="col-md-3"></article>
          </div>
        )
      }else{
          content.push(<article key={product.id} className="col-md-3"></article>);
      }
  });
  return (
    <div>
        {content}
    </div>
  );
}

答案 2 :(得分:1)

你想为每4列包装新行,对吗?

试试这个

render() {
		const products = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
		let rowContents = [];
		const contents = products.reduce((acc, p, i) => {
			rowContents.push(<div key={i} className="col col-md-3">Col {p}</div>);
			if (i % 4 === 3) {
				acc.push(<div className="row">{rowContents}</div>);
				rowContents = [];
			}
			return acc;
		},[])
       contents.push(<div className="row">{rowContents}</div>);

		return (
			<div>
			{contents}
			</div>
		)
	}

答案 3 :(得分:1)

Bootstrap的好处是,您可以将所有col*保留为单个 row,然后每4个插入一个全角div列以强制换行。这些使事情变得更简单,您不必分块数据。

这是React渲染的样子:

render() {
    let columns=[];
    this.props.items.forEach((item,idx) => {

        // push column
        columns.push(
            <div className="col-sm py-3" key={idx}>
                Content
            </div>
        )

        // force wrap to next row every 4 columns
        if ((idx+1)%4===0) {columns.push(<div className="w-100"></div>)}
    })


    return (
        <div className="row">
        {columns}
        </div>
    )            
}

演示: https://www.codeply.com/go/VMV26jhHFz

注意:在 Bootstrap 4 中,使用<div className="w-100"></div>,如上所示。在引导程序3 中,使用<div className="clearfix"></div>强制列包装每个 n

答案 4 :(得分:0)

您可以这样做:

render() {

    function toChunkArray(myArray: any, chunkSize: any): any {
        var results = [];

        while (myArray.length) {
            results.push(myArray.splice(0, chunkSize));
        }

        return results;
    }

    let chunkedArraysOfColSize = toChunkArray(myList, 3);

    return (
        <div className="row">
            {
                chunkedArraysOfColSize.map( (colSizeArray, index) =>
                    <div className="col-sm-4" key={index.toString()}>
                        {colSizeArray.map((o, i) =>
                            <NameOfComponent key={o.Id} obj={o} />
                        )}
                    </div>
                )
            }
        </div>
    );
}

答案 5 :(得分:0)

你可以有一行,所有列(col-md-3)都可以进入。要在每个第4列之后实现多行效果,您可以将样式设置为每个第4列,如下所示 -

<div className="col-md-3" style={{clear: (index != 0 && index % 4 == 0) ? 'both' : 'none'}}></div>

这将获得与具有多行相同的结果。

答案 6 :(得分:0)

当前所有答案似乎并不是Silly, Stupid,因为那里只关注一次打印一组项目,而没有考虑对具有不同项目数量的行的进一步处理。以下答案使用打字稿,但可以在香草JS中简单实现。我也使用lodash chunk作为一种便利,尽管您自己的分块方法很容易在需要时添加。

import * as _ from 'lodash'

export enum flexChunkOptions {
    col1 = 12,
    col2 = 6,
    col3 = 4,
    col4 = 3,
    col6 = 2,
    col12 = 1
}


export const chunkIntoFlexgrid = (numbOfItemsInRow: flexChunkOptions, arrayOfItems: ArrayLike<any>) => {
    return _.chunk(arrayOfItems, numbOfItemsInRow)
}

在上面的代码中,我们创建了一个枚举,该枚举具有所有可被12整除的引导程序列定义。这样做很简单,因此我们可以轻松地在模板中使用相应的col定义。我们期望接收到任何类型的项的数组(ts用户ArrayLike<any>的类型安全性要比any更好)。之后,如果我们选择[[1,2,3], [1,2,3]],我们将返回一个分块的数组,类似于col-3

const myArrOfItems = [1, 2, 3, 4, 5, 6, 7, 8]

{chunkIntoFlexgrid(flexChunkOptions.col3, mySetOfItems).map((el, i) => {
                        return <div key={ `row-${ i }` } className={ `row` }>
                            {
                                el.map(item => item)
                            }
                        </div>
                    })

在我们的模板中,我们可以简单地调用我们的connncence方法,并提供我们希望如何生成行的方法,并且可以简单地使用外部el变量来处理单个元素。

这里是lodash chunk documentation

的链接