React:每 4 列渲染一次新行

IT技术 twitter-bootstrap reactjs
2021-04-09 19:43:08

我正在使用react并且我想要render每 4 列一个新行。

我的代码:

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>
6个回答
  1. 将您的产品分成(最多)4 个元素的行,即

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

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

要计算行数,假设每行 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,因为splice变异的原始数组)。结果是一个数组数组(项目行)。

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

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

const Products = (props) => {
    // array of N elements, where N is the number of rows needed
    const rows = [...Array( Math.ceil(props.products.length / 4) )];
    // chunk the products into the array of rows
    const productRows = rows.map( (row, idx) => props.products.slice(idx * 4, idx * 4 + 4) ); );
    // map the rows as div.row
    const content = productRows.map((row, idx) => (
        <div className="row" key={idx}>    
          // map products in the row as article.col-md-3
          { row.map( product => <article key={product} className="col-md-3">{ product }</article> )}
        </div> )
    );
    return (
        <div>
          {content}
        </div>
    );
}
我真的不明白这里发生了什么。即使我修改了代码,也无法使您的代码正常工作...
2021-05-22 19:43:08
@maverick 编辑了答案以解释概念。一个重要的变化是slice代替splice它可能引起了一些问题。如果它在小提琴中对您有用,但在您的实现中不起作用,请跟进MCVE
2021-05-26 19:43:08
你好。Look Array( Math.ceil(props.products.length / 4) 总是给空
2021-05-28 19:43:08
@pawel 这应该是公认的答案。接受的答案是不准确的,因为如果您的父标签关闭,您就不能与孩子在同一行。感谢帕维尔的回答。那边很不错的代码
2021-06-21 19:43:08

像这样写:

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>
  );
}
嗯……我明白了!但是现在有 3 行,但每行只有 1 列......?遗漏了什么?
2021-06-05 19:43:08
没有让你正确,你能显示任何图像或以某种方式,你期望的结果是什么,你得到了什么?
2021-06-05 19:43:08
1 Row > Column Column Column 2 Row > Column Column Column 依此类推第四
2021-06-05 19:43:08
明白了,检查更新的答案:),在这种情况下,我们可以使用 map,因为我们需要为每个元素返回一些内容:)
2021-06-11 19:43:08
嗯,每一列都有自己的行......我想要每行 4 列。如果该行有 4 列,则应创建一个新行。
2021-06-18 19:43:08

Bootstrap 的好处是你可以将所有的都保存col*在一个单独的 中 row,然后div每 4 列插入一个全角来强制换行。这些使它更简单,您不必对数据进行分块。

这是 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>如上所示。Bootstrap 3 中,用于<div className="clearfix"></div>强制列每n换行

您想为每 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>
		)
	}

你可以这样做:

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